[英]atomic read then write with std::atomic
假设以下代码
#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
方法似乎就是您所追求的(重点是我的):
用期望的原子替换基础值。 该操作是读-修改-写操作。
用法如下:
auto localValue = val.exchange(0);
std::cout << "Value = " << localValue << std::endl;
正如其他人提到的, std::atomic::exchange
可以工作。
要提及为什么您的当前代码在执行的两行之间做到了您所说的:
std::cout <<"val="<< val << std::endl; val = 0;
其他两个线程有时间增加ht
线程将要重置的值。
std::atomic::exchange
将在一个“ atomic”操作中执行这些行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.