2013-07-12 11 views
10

は、私はC++でのスレッドプールを開発しようとすると、ワーカースレッドのメインループで)(スレッドを生成するか、条件変数を待つ方が良い場合、私は疑問に思う:スレッドプールの実装:condition_variables対収量()

void worker_thread(void) 
{ 
    // this is more or less pseudocode 

    std::unique_lock<std::mutex> lk(mutex_); 
    while(!done) 
    { 

     if(task_available) 
      run_task(); 
     else 
      condition_.wait(lk); 
    } 
} 

任意のアイデア対

void worker_thread(void) 
{ 
    // this is more or less pseudocode 
    while(!done) 
    { 

     if(task_available) 
      run_task(); 
     else 
      std::this_thread::yield(); 
    } 
} 

?両方のバージョンの間にパフォーマンスの違いはありますか?

答えて

7

スレッドプール内の自分のスレッドは常にタスクを与え、あなたは速い応答時間を必要としている場合は、収率が何をしたいですが、収量は関係なく、待機中のスレッドが何をしているのか、CPUサイクルを燃やすません。 条件付きアプローチを使用すると、スレッドはタスクが準備完了になるまでスリープします(ただし、準備完了信号が送信されていなくても条件付きでスレッドを復帰させることができます)。応答時間は遅くなりますが、燃焼CPUサイクル。

私は条件付きのアプローチを推奨し、反応時間が遅すぎる場合は、得に切り替えます。

+1

条件付きアプローチはどのように実装されていますか?彼らは上記のworker_threadと同様の待機メカニズムを持っていますか? – headmyshoulder

+1

yieldは、現在のプロセッサ上で実行する準備ができている別のスレッド(ウィンドウの場合、SwitchToThreadを参照)に呼び出しスレッドを実行させます。条件の場合は –

+0

、pthread_cond_waitを参照してください。 (ウィンドウ上のイベントのように)条件が成立するまで、スレッドはスリープ状態になります。 –

5

スレッドスイッチのコストはいずれの場合も同じです。ポーリングまたは条件変数のどちらを使うべきかについては、後者は本当に何かがあるまでスレッドを蹴飛ばしてプロセッサを休ませることができます。その結果、CPU使用率が低下します。ポーリング方法は、スレッドを戻して「やり直す」ことを可能にし、効果的にCPUを無期限に実行します。

task_availableが非常に短い時間(つまり、通常は作業がある)間違っているような、ポーリングを好むアプリケーションがいくつかあることを指摘しておきます。その場合は、カウンターを使用してループ内でtask_availableをポーリングします。カウンタがしきい値を超えた場合にのみスレッドを生成します。

関連する問題