1

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) {
    ....
  }
}
4

1 回答 1

3

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

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

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

于 2014-01-02T15:14:44.293 回答