2017-08-24 52 views
0

假定以下代码原子读取然后用写的std ::原子

#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:我不想作任何锁定

+1

也许['std :: atomic :: exchange'](http://en.cppreference.com/w/cpp/atomic/atomic/exchange) –

回答

2

std::atomic::exchange方法似乎是你后(重点煤矿)是什么:

以原子与所需替换潜在价值。操作是读取 - 修改 - 写入操作。


使用方法如下:

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

oook,这几乎是显而易见的!谢谢! – Sinapse

1

正如其他人所提到std::atomic::exchange会工作。

要提一下,为什么你当前的代码不会你说的话,执行的两条线之间:

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

其他两个线程有​​时间递增值ht线程即将复位。

std::atomic::exchange将在一个“原子”操作中执行这些行。