2013-07-03 7 views
5

私は並列で実行されるタスクを受け取るC++でスレッドプールクラスを作成しています。可能であれば、すべてのコアがビジー状態になるようにしたいが、時には同期目的でブロックされているため、あるスレッドはアイドル状態になることがあります。これが起こると、新しいスレッドを開始したいので、CPUコアと同じくらい多くのスレッドが常に起動するようにします。この目的のためには、特定のスレッドが起きているか眠っている(ブロックされている)かどうかを調べる方法が必要です。これをどのように見つけることができますか?スレッドがブロックされているかどうかを調べる方法はありますか?

私はC++ 11標準ライブラリを使用するか、移植性を高めることをお勧めします。しかし、必要ならばWinAPIも使用します。私はWindows 7上でVisual Studio 2012を使用していますが、実際には、これを行うための移植可能な方法が必要です。

好ましくは、このスレッドプールが100件のスレッドがそれを呼び出しまで

MyThreadPool pool; 
for (int i = 0; i < 100; ++i) 
    pool.addTask(&block_until_this_function_has_been_called_a_hundred_times); 
pool.join(); // waits until all tasks have been dispatched. 

機能block_until_this_function_has_been_called_a_hundred_times()ブロック状のケースをマスターすることができなければなりません。この時点で、すべてのスレッドは実行を継続する必要があります。スレッドプールの要件の1つは、プール内のスレッド数が少なすぎるためにデッドロックしないことです。

+0

当時のCPU使用量を測定できました。しかし、あなたの閉塞が本当にかなり長い場合(ロックのラッパーを持っている場合は、「どれくらい長くスリープするか」という統計情報を保持することができます)、スレッドがブロックされるよりも新しいスレッドを開始するにはもっと時間がかかるでしょう。私はこれを行う標準的な方法を知らない。 –

+0

ブロックされているとはどういう意味ですか?あなたのスレッドの一部がブロックされているためにアイドル状態になっている場合、別のスレッドのヘルプを開始すると、既存のスレッドと同じリソースを待ってアイドル状態になりませんか? @MatsPeterssonによれば、スレッドのアイドル時間を測定できると言われていますが、おそらくリソースのスループットを測定してスレッドを可能な限りビジーに保つ必要があります。 – dwxw

+0

なぜ迷惑でしょうか?十分な数の余分なスレッドをプールに確保するだけです。 –

答えて

2

Boost Asioを使用してください。独自のスレッドプール管理およびスケジューリングフレームワークを備えています。基本的な考え方は、post()メソッドを使用してio_serviceオブジェクトにタスクをプッシュし、多くのCPUコアと同じ数のスレッドからrun()を呼び出します。十分なジョブがない場合にスレッドが終了しないように、計算が実行されている間にworkオブジェクトを作成する必要があります。

Asioの重要なことは、決してブロッキングコールを使用しないことです。 I/Oコールでは、Asio独自のI/Oオブジェクトの非同期呼び出しを使用します。同期のために、mutexの代わりにオブジェクトを使用してください。ストランドに包まれたioサービスに機能をポストすると、いつでも最大1つのタスクが特定のストランドに属していることが保証されます。競合が発生した場合、タスクは動作中のスレッドをブロックするのではなく、Asioのイベントキューに残ります。

ただし、非同期プログラミングを使用すると1つの欠点があります。いくつかの非同期呼び出しに分散しているコードを、明確な制御フローを持つものよりも読むのがずっと難しくなります。プログラムを設計するときは、このことに注意する必要があります。

2

「私はブロックされました」と「それ以上ブロックされていません」と言うスレッドを見つけるためにスレッドプールに機能を追加します。すべての重要なブロックアクション(私がそのことを意味するものについては下記を参照)の前に、「ブロックされています」と通知し、その後は「ブロックされなくなりました」。

「重要なブロックアクション」とは何ですか?確かに単純なミューテックスロックではありません。ミューテックスは短期間しか保持されないため、ミューテックスでのブロックは大したことではありません。共有キュー

や他の同様のイベントにデータを待っ

  • を完了するために、別のプールのタスクを待っている
  • 完了するために、I/Oを待機

    • :私のようなものを意味します。

  • +0

    私の答えをより完全かつ構造化してくれてありがとう:) – Dennis

    関連する問題