在 Linux 内核源代码中,存在许多内存屏障(smp_mb() 等)。
但是在redis的源码中,并没有看到。在redis的Makefile中,gcc优化选项是-O2,所以应该对这些指令重新排序。为什么它不使用 mb() 来确保正确的行为?
添加:
例如:在 Linux 内核的 kfifo 中:
unsigned int __kfifo_put(struct kfifo *fifo,unsigned char *buffer, unsigned int len)
{
unsigned int l;
len = min(len, fifo->size - fifo->in + fifo->out);
smp_mb();
l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
...
smp_wmb();
fifo->in += len;
...
}
在 Redis 源码中,我研究了整个项目,找不到内存障碍:例如:
zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned int rank[ZSKIPLIST_MAXLEVEL];
int i, level;
...
level = zslRandomLevel();
if (level > zsl->level) {
for (i = zsl->level; i < level; i++) {
rank[i] = 0;
update[i] = zsl->header;
/////need a mb() ???
update[i]->level[i].span = zsl->length;
}
zsl->level = level;
}
...
}
为什么在redis中没有内存屏障有什么特别的吗?
我认为我对 mb() 的理解可能不成熟,感谢您的评论...
添加:
但是在上面显示的两段代码中,linux内核中的kfifo使用了mb()。它只是更改分配在线程堆栈空间中的变量以及用户 mb() 在 r/w 操作之间。所以它不应该完全与多线程相关......(虽然redis是单线程)