原子读然后写 std::atomic

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 方法似乎是您所追求的(强调我的):

Atomically replaces the underlying value with desired. The operation is read-modify-write operation.


使用如下:

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" 操作中完成这些行。