在我的应用程序中,我有一个int和一个bool变量,由多个线程访问(多次写/读)。目前,我使用两个互斥锁,一个用于int,一个用于bool来保护这些变量。
我听说过使用原子变量和运算符来编写无锁多线程程序。我的问题是
这些代码是否是线程安全的?
double double_m; // double_m is only accessed by current thread.
std::atomic<bool> atomic_bool_x;
atomic_bool_x = true && (double_m > 12.5);
int int_n; // int_n is only accessed by current thread.
std::atomic<int> atomic_int_x;
std::atomic<int> atomic_int_y;
atomic_int_y = atomic_int_x * int_n;
答案 0 :(得分:16)
我不是专家或其他任何人,但这就是我所知道的:
std::atomic
只是说同时调用load
和store
(以及其他一些操作)是明确定义的。原子操作是不可分割的 - 在'之间'没有任何事情可以发生。std::atomic
基于boost::atomic
。如果可以,请使用std
,否则请使用boost
。std
完全是可移植的,但是你的编译器需要支持C ++ 11 std::atomic_bool
。你不应该使用volatile。此外,我相信load
/ store
与operator=
/ operator T
不同,只有 load
/ store
是原子的
没关系。我检查了标准,似乎运算符是根据load
/ store
/等定义的,但它们可能会返回不同的内容。
进一步阅读:
答案 1 :(得分:7)
易失性与用于实现原子的方法正交。在C ++中,它告诉编译器确定使用该变量执行优化是不安全的。 Herb Sutters说出来了:
为了安全地编写在不使用锁的情况下在线程之间进行通信的无锁代码,更喜欢使用有序的原子变量:Java / .NET volatile,C ++ 0x atomic和C兼容的atomic_T。
要安全地与具有异常语义的特殊硬件或其他内存通信,请使用不可优化的变量:ISO C / C ++ volatile。请记住,这些变量的读写不一定是原子的。
最后,为了表达一个变量,它既有不寻常的语义,又具有无锁编码所需的任何或全部原子性和/或排序保证,只有ISO C ++ 0x草案标准提供了拼写它的直接方法:volatile atomic。
(来自http://drdobbs.com/article/print?articleId=212701484&siteSectionName=parallel)
答案 2 :(得分:2)
std::atomic
是自C ++ 11以来的标准,而Boost的东西更老。但由于它现在是标准的,我更希望std::atomic
。std::atomic
和每个C ++ 11编译器。没有任何进一步的信息......
的std ::原子;
答案 3 :(得分:1)
我相信std::atomic
(C ++ 11)和boost.atomic
是等价的。如果您的编译器尚未支持std::atomic
,请使用boost::atomic
。