简体   繁体   English

原子读取,然后用std :: atomic写入

[英]atomic read then write with std::atomic

Assume the following code 假设以下代码

#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;
}

It is basically two threads incrementing the value of val and a third thread which reports this value every second then resets it. 基本上是两个线程递增val的值,第三个线程每秒报告一次该值,然后将其重置。 The problem is, when the third thread is reading this value and then sets it to zero, there can be possible increments which will be lost (we did not include them in report). 问题是,当第三个线程读取该值然后将其设置为零时,可能会有可能丢失的增量(我们未在报告中包括它们)。 So we need an atomic read-then-write mechanism. 因此,我们需要一种原子的“先读后写”机制。 Is there a clean way to do this that I am not aware of? 有没有我不知道的干净方法来做到这一点? PS: I don't want to lock anything PS:我不想锁定任何东西

The std::atomic::exchange method seems to be what you're after (emphasis mine): std::atomic::exchange方法似乎就是您所追求的(重点是我的):

Atomically replaces the underlying value with desired. 用期望的原子替换基础值。 The operation is read-modify-write operation. 该操作是读-修改-写操作。


Use as follows: 用法如下:

auto localValue = val.exchange(0);
std::cout << "Value = " << localValue << std::endl;

As others mentioned std::atomic::exchange would work. 正如其他人提到的, std::atomic::exchange可以工作。

To mention why your current code does what you said, between the two lines of execution: 要提及为什么您的当前代码在执行的两行之间做到了您所说的:

 std::cout <<"val="<< val << std::endl; val = 0; 

the other two threads have time to increment the value that ht thread is about to reset. 其他两个线程有​​时间增加ht线程将要重置的值。

std::atomic::exchange would do those lines in one "atomic" operation. std::atomic::exchange将在一个“ atomic”操作中执行这些行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM