如果我有这样的原子变量:
#include <atomic>
std::atomic<int> a = 5;
我想原子地检查(a + 4)
是否小于另一个变量,而不会覆盖a
的原始值:
if(a.something(4) < another_variable){
//Do not want a to be incremented by 4 at this point
}
我对原子fetch_and_add()
和++
进行了快速测试,之后他们似乎都增加了变量a
的值。有没有办法可以原子地增加测试,而结果不是永久性的?
答案 0 :(得分:3)
if(a + 4 < another_variable) // ...
这是使用单个原子获得的最佳效果。您是数据争用的,因为读取原子对于并发写入是安全的,并且所有后续操作都发生在原始原子值的副本上。一个更详细但功能相同的版本是:
int const copy_of_a = a.load();
if(copy_of_a + 4 < another_variable) // ...
这也是同步方面的最佳选择。您可能会担心a
可能会在另一个线程上更改为会更改if
结果的值。
假设有一个函数以原子方式完成整个操作:
if(a.plus4IsLessThan(another_variable) // ...
然后,a
的并发更改是否及时到达以更改测试结果仍然未知。您在同步方面没有获得任何额外保证。
如果这是您的程序的问题,则表明您需要更强大的同步机制。可能std::mutex
可能是一个好的开始。
答案 1 :(得分:1)
你可以这样做:
if (a + 4 < another_variable) { ...
哪个应该与:
相同if (a.load() + 4 < another_variable) { ...
根据定义(§29.6.5/ 16-17,这里A
“指的是原子类型之一”和“C
引用其对应的非原子类型”):
A::operator C() const volatile noexcept;
A::operator C() const noexcept;
效果:
load()
返回:
的结果load()
两者均未修改a
。