2017-08-24 85 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將在一個「原子」操作中執行這些行。