原子读取然后使用std :: atomic

时间:2017-08-24 10:39:07

标签: c++ multithreading 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:我不想锁定任何东西

2 个答案:

答案 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会在一次“原子”操作中执行这些行。