这里需要内存屏障“* pEnd_ = v; __sync_synchronize(); ++ pEnd_;”?

时间:2014-01-02 14:40:59

标签: c++ multithreading memory barrier

pEnd_是一个对象成员,只能在一个线程中增加add(),如下所示,它可能被另一个线程读取。我们在add()中需要__sync_synchronize吗?

struct Vector {
    ...
    void add(int v) {
        *pEnd_ = v;
        __sync_synchronize(); // is this needed?
        ++pEnd_;
    }
private:
    int* pBegin_;
    int* pEnd_;
}

在另一个线程中迭代。

for (p = pBegin_; p != pEnd_; ++p) {
  // read barrier here may be inserted 
  if (*p) {
    ....
  }
}

1 个答案:

答案 0 :(得分:3)

至少没有释放内存屏障,您对*pEnd所做的修改不一定对其他线程可见。所以需要一些东西。

严格来说,不需要__sync_synchronize(),因为它是一个完整的内存屏障。如果您的编译器没有仅发布屏障(也就是“写屏障”)的内在函数,那么完整的屏障是合理的。

从表面上看,由于pEnd的增量对来自其他线程的读取没有排序,导致数据竞争。特定平台可能会保证int*访问是原子的,并且还可以保证变更在其他线程中以与在此线程中编写的顺序相同的顺序变为可见。所以在某些平台上代码是可以的(并且完整的屏障可以防止写入被重新排序)。这些都不是标准的C ++,并且它可能特定于硬件而不是编译器。