Bru*_*ice 4 c++ multithreading atomic compare-and-swap stdatomic
我读过https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange
以原子方式将 *this 的对象表示形式 (C++20 之前) 值表示形式 (C++20 起) 与预期的表示形式进行比较,如果它们按位相等,则将前者替换为所需的(执行读取-修改-写入操作) )。否则,将 *this 中存储的实际值加载到预期中(执行加载操作)。
据我了解,代码如下
bool expected=true;
extern atomic<bool> b = false;
void foo ()
{
//
while(!b.compare_exchange_weak(expected, false));
//
}
Run Code Online (Sandbox Code Playgroud)
循环运行一次后(忽略虚假失败)它将失败,并将写入预期false
,因此在第二次迭代时,compare_exchange_weak将返回成功,尽管b
尚未更改为true。但这一切有什么意义呢?我虽然可以用它作为同步锁,等待其他线程更改b
,但现在我想不出它的用法。
cppreference 中的示例还表明,两次调用compare_exchange_strong 后将会成功。
#include <atomic>
#include <iostream>
std::atomic<int> ai;
int tst_val= 4;
int new_val= 5;
bool exchanged= false;
void valsout()
{
std::cout << "ai= " << ai
<< " tst_val= " << tst_val
<< " new_val= " << new_val
<< " exchanged= " << std::boolalpha << exchanged
<< "\n";
}
int main()
{
ai= 3;
valsout();
// tst_val != ai ==> tst_val is modified
exchanged= ai.compare_exchange_strong( tst_val, new_val );
valsout();
// tst_val == ai ==> ai is modified
exchanged= ai.compare_exchange_strong( tst_val, new_val );
valsout();
}
Run Code Online (Sandbox Code Playgroud)
结果:
ai= 3 tst_val= 4 new_val= 5 exchanged= false
ai= 3 tst_val= 3 new_val= 5 exchanged= false
ai= 5 tst_val= 3 new_val= 5 exchanged= true
Run Code Online (Sandbox Code Playgroud)
std::atomic::compare_exchange_weak
以线程感知的方式执行此英语任务:
因为变量成立
expected
,所以它现在应该成立desired
。
作为一项微不足道的任务,想象一下您的价值std::atomic<int> x
应该平方。但其他线程可能正在修改它,因此您不能简单地读取该值,对其求平方并将新值写回。读完后数值可能会改变!
这是执行此任务的线程安全方法。您可以保证存储的值将被替换为它的平方。
int expected = x;
while( !x.compare_exchange_weak(expected, expected*expected) );
Run Code Online (Sandbox Code Playgroud)
除非该值已更改,否则此代码将自动替换expected
为其平方。
如果该值已更改,expected
则现在使用新值进行更新,并且代码会再次尝试。
归档时间: |
|
查看次数: |
1066 次 |
最近记录: |