首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在Redis源代码中我看不到内存屏障?

为什么在Redis源代码中我看不到内存屏障?
EN

Stack Overflow用户
提问于 2013-01-06 17:21:14
回答 2查看 343关注 0票数 2

在Linux内核源代码中,存在许多内存屏障(smp_mb()等)。

但在redis的消息来源里,我没看到。在redis的Makefile中,gcc优化选项是-O2,所以需要对这些指令进行重新排序。为什么不使用mb()来确保正确的行为呢?

添加:

例如:在Linux内核的kfifo中:

代码语言:javascript
复制
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源码中,我研究了整个项目,找不到内存屏障:例如:

代码语言:javascript
复制
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()。所以它不应该完全与多线程相关…(虽然redis是单线程)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-07 00:23:51

Redis是单线程的,所以不需要内存屏障。

只有当你有多个执行路径时(例如在多线程应用程序中),它们才是相关的。即使使用多线程用户空间应用程序,您通常也不需要自己的内存屏障,因为库(例如pthread)在同步API中包含内存屏障(例如互斥、信号量、条件变量等)。

票数 6
EN

Stack Overflow用户

发布于 2013-01-06 17:32:46

认识到很少的代码需要显式的内存屏障可能会有所帮助。这类代码的一些例子包括操作系统内核、线程库和无锁数据结构。

大多数其他代码可能会:

  1. 不直接与线程交互,呈现操作系统提供的线程库(例如pthreads)的内存障碍,并且依赖于此类库提供的memory ordering guarantees

如果你在问这个问题时,考虑到了Redis代码库的某个特定部分,请向我们展示相关代码。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14180796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档