原子读取然后用 std::atomic 写入
Posted
技术标签:
【中文标题】原子读取然后用 std::atomic 写入【英文标题】:atomic read then write with std::atomic 【发布时间】:2017-08-24 10:39:06 【问题描述】:假设以下代码
#include <iostream>
#include <atomic>
#include <chrono>
#include <thread>
std::atomic<uint> val;
void F()
while(true)
++val;
void G()
while(true)
++val;
void H()
while(true)
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout <<"val="<< val << std::endl;
val = 0;
int main()
std::thread ft(F);
std::thread gt(G);
std::thread ht(H);
ft.join();
gt.join();
ht.join();
return 0;
基本上是两个线程递增val
的值,第三个线程每秒报告这个值然后重置它。问题是,当第三个线程读取该值然后将其设置为零时,可能会丢失增量(我们没有将它们包含在报告中)。所以我们需要一个原子的读写机制。有没有一种我不知道的干净方法来做到这一点?
PS:我不想锁定任何东西
【问题讨论】:
或许std::atomic::exchange
【参考方案1】:
std::atomic::exchange
方法似乎是您所追求的(强调我的):
以原子方式将基础值替换为期望值。操作是read-modify-write操作。
如下使用:
auto localValue = val.exchange(0);
std::cout << "Value = " << localValue << std::endl;
【讨论】:
【参考方案2】:正如其他人提到的那样,std::atomic::exchange
会起作用。
在两行执行之间提及为什么您当前的代码执行您所说的:
std::cout <<"val="<< val << std::endl; val = 0;
其他两个线程有时间递增ht
线程即将重置的值。
std::atomic::exchange
将在一个“原子”操作中完成这些行。
【讨论】:
以上是关于原子读取然后用 std::atomic 写入的主要内容,如果未能解决你的问题,请参考以下文章