在Linux內核源代碼中,有很多內存屏障(smp_mb()等)。爲什麼在Redis源代碼中我沒有看到內存障礙?
但在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() 。它只是改變線程堆棧空間中分配的變量以及r/w操作之間的用戶mb()。所以它不應該完全相關於多線程......(雖然redis是單線程的)
這個問題太含糊。爲了使其具體,請顯示一些您認爲需要內存屏障才能正確操作的Redis代碼,但不使用它。 – NPE
謝謝,我重新編輯它 –
我對Redis的代碼庫一無所知。是否有理由認爲您展示的跳過列表實現意味着線程感知,讓線程安全? – NPE