std::atomic是否阻止非原子变量相对于原子变量的重新排序



问题相当简单Q:如果我有

settings[N_STNGS];//used by many threads  
std::atomic<size_t> current_settings(0);
void updateSettings()//called by single thread  , always the same thread if that is important
{
    auto new_settings = (current_settings+1)%N_STNGS;
    settings[new_settings].loadFromFileSystem(); //line A
    current_settings=new_settings; //line B
}

标准能保证A线不会在B线之后重新订购吗?STNGS的用户是否会始终看到一致的(承诺为内存中可见的可见性)数据?

编辑:对于多个读取器线程和非平凡的设置,与简单的互斥相比,这值得麻烦吗?

给定的定义

int settings[N_STNGS];
std::atomic<size_t> current_settings(0);

线程1执行:

settings[new_settings] = somevalue;  // line A
current_settings=new_settings;       // line B

线程2执行:

int cur_settings = current_settings;        // line X
int setting_value = settings[cur_settings]; // line Y

那么是的,如果X行的线程2读取了由B行的线程1写入的new_settings,并且对settings[new_settings]没有其他修改(通过一些我们看不到的代码),则线程2绑定为读取somevalue,并且没有发生未定义的行为。这是因为所有操作都是(默认情况下)memory_order_seq_cst,并且释放写入(行B)与获取读取(行X)同步。请注意,在线程2中需要两条语句来获得索引的原子读取和值的读取之间的先序后序关系(memory_order_consume操作可以代替)。

我当然会先用rw互斥实现它。

一般答案是否定的。如果你很小心,只使用具有memory_order参数的函数,并根据你正在做的事情为它们传递正确的值,那么它可能是肯定的。

(正如其他人所指出的,您的代码有问题。例如,按值返回原子<>类型对我来说没有意义。)

最新更新