假设以下代码
#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:我不想锁定任何东西
答案 0 :(得分:3)
std::atomic::exchange
方法似乎就是你所追求的(强调我的):
以原子方式替换所需的基础值。该操作是读 - 修改 - 写操作。
使用如下:
auto localValue = val.exchange(0);
std::cout << "Value = " << localValue << std::endl;
答案 1 :(得分:2)
正如其他人提到的那样std::atomic::exchange
会起作用。
要提及为什么你当前的代码在两行执行之间完成你所说的话:
std::cout <<"val="<< val << std::endl; val = 0;
其他两个线程有时间递增ht
线程即将重置的值。
std::atomic::exchange
会在一次“原子”操作中执行这些行。