内容
- redis中的内存调配api
- redis中的原子操作api
源代码
Redis中的内存调配和原子操作
代码构建
cp /home/vagrant/github/server_installer/servers/redis/redis-6.2/src/zmalloc.* .cp /home/vagrant/github/server_installer/servers/redis/redis-6.2/src/atomicvar.h .
zmalloc.c中援用了config.h, 删除掉
新建server.c, 内容如下
#include "stdio.h"#include "atomicvar.h"#include "zmalloc.h"int main(int argc, char **argv){ redisAtomic long long i = 10; atomicIncr(i, 3); printf("hello %lld\n",i); char *p; p = zmalloc(10); p = "hello"; printf("hello %s\n",p); int accurate; accurate = 10;#ifdef REDIS_TEST zmalloc_test( argc,argv,accurate );#endif return 0;}
新建Makefile
server : zmalloc.o server.o $(CC) -o $@ $^%.o: %.c $(CC) -DREDIS_TEST=1 -MMD -o $@ -c $<.PHONY: cleanclean: rm -rf *.o *.d server
再看一下zmalloc_test
的内容
#ifdef REDIS_TEST#define UNUSED(x) ((void)(x))int zmalloc_test(int argc, char **argv, int accurate) { void *ptr; UNUSED(argc); UNUSED(argv); UNUSED(accurate); printf("Malloc prefix size: %d\n", (int) PREFIX_SIZE); printf("Initial used memory: %zu\n", zmalloc_used_memory()); ptr = zmalloc(123); printf("Allocated 123 bytes; used: %zu\n", zmalloc_used_memory()); ptr = zrealloc(ptr, 456); printf("Reallocated to 456 bytes; used: %zu\n", zmalloc_used_memory()); zfree(ptr); printf("Freed pointer; used: %zu\n", zmalloc_used_memory()); return 0;}#endif
输入
hello 13hello helloMalloc prefix size: 0Initial used memory: 24Allocated 123 bytes; used: 160Reallocated to 456 bytes; used: 480Freed pointer; used: 24
解释
对于zmalloc函数,能够间接对应到c规范库里的malloc, realoc, free函数,redis会依据不同的实现调用不同的内存调配库,以实现更好的性能以及更多的性能。因为redis中曾经写好测试了,咱们就间接调用了。这外面用到了预编译。失常的编译不会把测试函数编译进redis server中的。在编译多c文件中,没有制订如何生成*.o文件。当用上篇文章中的Makefile编译时会晋升找不到zmalloc_test
的实现。通过查看redis的Makefile, 发现了
%.o: %.c $(CC) -DREDIS_TEST=1 -MMD -o $@ -c $<
外面的MMD是什么含意呢,上面参考文章有具体的解释,这里总结一下
. M 依赖的文件
. MM 去除#include
援用的依赖后的依赖
. D 是生成依赖文件,后缀为.d, 所以有MD 和MMD,这里用的MMD
linux下原子操作是C11中的封装。
gcc -MM zmalloc.c
输入为:zmalloc.o: zmalloc.c zmalloc.h atomicvar.h
redis zmalloc & atomic api
- size_t zmalloc_used_memory(void) -- 动静分配内存
- void *zmalloc(size_t size)--分配内存
- void zrealloc(void ptr, size_t size)-- 从新分配内存
- void zfree(void *ptr) -- 开释内存
- atomicIncr(var,count) -- 原子加
- atomicGetIncr(var,oldvalue_var,count) -- Get and increment the atomic counter
- atomicDecr(var,count) -- 原子减
- atomicGet(var,dstvar) -- 原子取
- atomicSet(var,value) -- 原子设置数
- atomicGetWithSync(var,value) -- 原子取, 不胜利始终循环
- atomicSetWithSync(var,value) -- 原子设置, 不胜利始终循环
参考
MMD含意