2011-06-30 12 views
2

ここでは、同期に関する合計n00bの質問があります。私は、それぞれの繰り返しで約束に別の値 'p'を割り当てる 'writer'スレッドを持っています。私はこの値のshared_futuresを待つ「読者」スレッドが必要です。そして、私の質問は、読者スレッドが 'p'の新しい更新を待つことを保証するためにfuture/promiseをどうすれば使うのですか?各反復?どうもありがとう。set_value()を反転して約束を無効にするにはどうしたらいいですか?

+1

すべての読者が同じ値の「p」で作業していますか?あるいは、それぞれのリーダーが異なる価値観を持って作業していますか?シングルライターのマルチリーダーキューは適切なものですか? – Managu

+0

私の場合、すべての読者は同じ値の 'p'で作業します。だから私の問題は、ライターの各反復で新しい値 'p'を設定し、各処理ステップが完了した後にこの新しい値を待つようにする方法です。 – MMagique

+1

あなたは本当に毎回新しい約束を発行し、同じ約束を再使用するべきではありません。 – Puppy

答えて

1

promise/futureペアは、1つの値(または例外)を持つように設計されています。あなたが描いていることをするには、おそらく別のツールを採用したいと思うでしょう。

複数のスレッド(読者)をすべて共通点で停止させたい場合は、barrierと考えることができます。

1

プロミスをブランクの約束に割り当てることで、プロミスを「リセット」することができます。

myPromise = promise<int>(); 

より完全な例:

promise<int> myPromise; 

void writer() 
{ 
    for(int i = 0; i < 10; ++i) 
    { 
     cout << "Setting promise.\n"; 
     myPromise.set_value(i); 

     myPromise = promise<int>{};  // Reset the promise. 

     cout << "Waiting to set again...\n"; 
     this_thread::sleep_for(chrono::seconds(1)); 
    } 
} 

void reader() 
{ 
    int result; 
    do 
    { 
     auto myFuture = myPromise.get_future(); 
     cout << "Waiting to receive result...\n"; 
     result = myFuture.get(); 
     cout << "Received " << result << ".\n"; 
    } while(result < 9); 
} 

int main() 
{ 
    std::thread write(writer); 
    std::thread read(reader); 

    write.join(); 
    read.join(); 

    return 0; 
} 

このアプローチの問題は、しかし、二つのスレッド間の同期は、作家がfuture::get()に読者の呼び出しの間何度もpromise::set_value()以上を呼び出すために引き起こすことができるということです約束がリセットされている間に呼び出されるfuture::get()。これらの問題は注意深く(例えば、呼び出し間の適切なスリーピングによって)回避することができますが、これは論理的に並行性を修正するのではなく、ハッキングと推測の領域に入ります。

約束事を新しい約束事に割り当てることで約束をリセットすることは可能ですが、そうすることで広範な同期問題が発生する傾向があります。

関連する問題