上一篇博文中,我介绍了zmalloc.c文件中几个常用的函数,接下来给大家介绍一下该文件中的其他函数,其实本文中的很多函数要比上一篇文章中的函数要更有趣的,并且涉及到很多操作系统的知识。前面几个函数比较简单,一笔带过,后面几个是学习的重点。
开胃菜
zmalloc_enable_thread_safeness
void zmalloc_enable_thread_safeness(void) {
zmalloc_thread_safe = 1;
}
zmalloc_thread_safe是一个全局静态变量(static int)。它是操作是否是线程安全的标识。1 表示线程安全,0 表示非线程安全。
zmalloc_used_memory
size_t zmalloc_used_memory(void) {
size_t um;
if (zmalloc_thread_safe) {
#if defined(__ATOMIC_RELAXED) || defined(HAVE_ATOMIC)
um = update_zmalloc_stat_add(0);
#else
pthread_mutex_lock(&used_memory_mutex);
um = used_memory;
pthread_mutex_unlock(&used_memory_mutex);
#endif
}
else {
um = used_memory;
}
return um;
}
该函数要完成的操作就是返回变量used_memory(已用内存)的值,所以它的功能是查询系统当前为Redis分配的内存大小。本身代码量不大,但是涉及到了线程安全模式下的查询操作。实现线程同步用到了互斥锁(mutex)。关于互斥锁的内容在上一篇文章中已经简要介绍过了。总之要记住的是加锁(pthread_mutex_lock)和解锁(pthread_mutex_unlock)。在加了互斥锁之后,就能保证之后的代码同时只能被一个线程所执行。
zmalloc_set_oom_handler
void zmalloc_set_oom_handler(void (*oom_handler)(size_t)) {
zmalloc_oom_handler = oom_handler;
}
该函数的功能是给zmalloc_oom_handler赋值。zmalloc_oom_handler是一个函数指针,表示在内存不足(out of memory,缩写oom)的时候所采取的操作,它的类型是void (*) (size_t)。所以zmalloc_set_oom_handler函数的参数也是void (*) (size_t)类型,调用的时候就是传递一个该类型的函数名就可以了。
不过zmalloc_oom_handler在声明的时候初始化了默认值——zmalloc_default_oom()。同样在上一篇博文中也有过介绍。
zmalloc_size
#ifndef HAVE_MALLOC_SIZE
size_t zmalloc_size(void *ptr) {
void *realptr = (char*)ptr-PREFIX_SIZE;
size_t size = *((size_t*)realptr);
/* Assume at least that all the allocations are padded at sizeof(long) by
* the underlying allocator. */
if (size&(sizeof(long)-1)) size += sizeof(long)-(size&(sizeof(long)-1));
return size+PREFIX_SIZE;
}
#endif
这段代码和我在上一篇博文中介绍的zfree()函数中的内容颇为相似。大家可以去阅读那一篇
博文。这里再概括一下,zmalloc(size)在分配内存的时候会多申请sizeof(size_t)个字节大小的内存【64位系统中是8字节】,即调用malloc(size+8),所以一共
申请分配size+8个字节,zmalloc(size)会在已分配内存的首地址开始的8字节中存储size的值,实际上因为内存对齐,malloc(size+8)分配的内存可能会比size+8要多一些,目的是凑成8的倍数,所以实际分配的内存大小是size+8+X【(size+8+X)%8==0 (0<=X<=7)】。然后内存指针会向右偏移8个字节的长度。zfree()就是zmalloc()的一个逆操作,而zmalloc_size()的目的就是计算出size+8+X的总大小。
--------------------------------------------------------------------------------------------------------------------------------------------------------------
这个函数是一个条件编译的函数&#x