2017-08-24 13 views
0

それは基本的にvalの値と、それをリセットし、この値を毎秒を報告する第三のスレッドをインクリメントする二つのスレッドであり、次のコードは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; 
} 

と仮定する。問題は、3番目のスレッドがこの値を読み取ってから0に設定すると、失われる可能性のあるインクリメントがある可能性があります(レポートにインクルードしていない)。だから我々は、原子の読み取りと書き込みのメカニズムが必要です。私が気付いていないこれを行うためのきれいな方法がありますか? PS:私はstd::atomic::exchange方法は、あなたが(強調鉱山)後にしているもののようです何

+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

通り。

あなたの現在のコードは、あなたが言ったことない理由実行の2行の間に、言及する:

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

、他の2つのスレッドがhtスレッドをリセットしようとしていること値をインクリメントする時間を持っています。

std::atomic::exchangeは、これらの行を1回の「アトミック」操作で実行します。

関連する問題