2016-07-04 10 views
1

ないすべてのスレッド()

condition_variable cv; 
mutex mut; 

// Thread 1: 
void run() { 
    while (true) { 
     mut.lock(); 
     // create_some_data(); 
     mut.unlock(); 
     cv.notify_all();   
    } 
} 

// Thread 2 
void thread2() { 
    mutex lockMutex; 
    unique_lock<mutex> lock(lockMutex); 
    while (running) { 
     cv.wait(lock); 
     mut.lock(); 
     // copy data 
     mut.unlock(); 
     // process data 
    } 
} 

// Thread 3, 4... - same as Thread 2 

は、私は、スレッド1、新たなデータを取得するためにすべての時間を実行します。他のスレッドは、新しいデータが利用できるようになるまでcondition_variableで待機し、それをコピーして処理します。スレッドによって完成された作業は、完了に必要な時間が異なります。スレッドは、古いもので終了したときにのみ新しいデータを取得するという考え方です。その間に取得されたデータは「欠落」することができます。私はスレッドをお互いに依存させたくないので、共有ミューテックス(データにアクセスするためだけ)を使用しません。

上記のコードはUbuntu上で動作しますが、notify_all()が呼び出されたときにただ1つのスレッドのみが通知されていて、wait()でハングするだけです。 なぜですか? Linuxではcondition_variableを使用するために異なるアプローチが必要ですか?

+1

'私はスレッドをお互いに依存させたくないので、共有ミューテックス(データにアクセスするためだけ)を使用しません。 ' - しかし、条件変数**を使うには**共有ミューテックスが必要です。他に方法はありません。 – Tsyvarev

答えて

2

運がうまくいっています。

mutexと条件変数は同じ構造の2つの部分です。 mutexとcvsを混在させて一致させることはできません。

これを試してみてください。

void thread2() { 
    unique_lock<mutex> lock(mut); // use the global mutex 
    while (running) { 
     cv.wait(lock); 
     // mutex is already locked here 
     // test condition. wakeups can be spurious 
     // copy data 
     lock.unlock(); 
     // process data 

     lock.lock(); 
    } 
} 
+0

シンプルで馬鹿な間違いのように見えるものはありがとうございます。ループの残りの部分でmutexをロックしないように私の要求を満たしているので、これを答えとして受け入れました。 – Pawel

1

this documentationパー:

STDで待機していきどれスレッド:: condition_variableはあり

  1. 取得のstd :: unique_lockのに、 共有変数を保護するのに使用されているものと同じmutexで
  2. wait、wait_for、wait_untilのいずれかを実行します。待機操作は、mutexを原子的に解放し、 スレッドの実行を一時停止します。
  3. 条件変数が通知されると、タイムアウトが満了するか、または擬似ウェークアップが発生し、スレッドが起動され、mutexがアトミックに再取得されます( )。スレッドはその後、条件 を確認し、起床が偽であった場合は待機を再開します。

このコード

void thread2() { 
    mutex lockMutex; 
    unique_lock<mutex> lock(lockMutex); 
    while (running) { 

はそれをしません。

2

あなたのコードは、待機中に終了したときにcvが再ロックしたユニークなロックを再ロックするので、直ちにUBを表示します。

偽のウェイクアップを検出しないなどの問題があります。

最後に、現在待機しているすべてのonky通知スレッドに通知します。スレッドが後で表示された場合は、ダイスは表示されません。

関連する問題