スレッドプール

スレッドプールは、作業割り当てを待つスレッドのグループで、スレッドを管理する効率的なアプローチを提供します。このアプローチでは、スレッドは、初期化ステップ中に作成され、終了化ステップ中に終了されます。アプリケーション全体を通して、スレッド作成中の失敗を途中で確認する制御ロジックを単純化できるので、アプリケーション全体でスレッド作成に必要なコストを減らすことができます。

いったん作成されると、スレッドプールのスレッドは作業が可能になるまで待機します。アプリケーションの他のスレッドは、スレッドプールにタスクを割り当てます。これは、スレッド・マネージャーやディスパッチャーと呼ばれる単一のスレッドです。タスクが完了すると、各スレッドは次の作業まで待機するためにスレッドプールに戻ります。作業量が増える場合、作業割り当てと使用されたスレッド・プール・ポリシーに応じて、スレッドプールに新しいスレッドを追加できます。このアプローチには、次の利点があります。

スレッドプールを使用する典型的な例として、新しいリクエストごとにスレッドを頻繁に起動するサーバー・アプリケーションがあります。この場合、既存のスレッドプールによって処理するサービスリクエストをキューすると、より効果的です。プールのスレッドは、キューのサービスリクエストを取得して処理し、次の作業のためにキューに戻ります。

スレッドプールは、オーバーラップしている非同期 I/O の実行にも使用できます。Win32* API で提供される I/O 完了ポートでは、スレッドのプールは I/O 完了ポートで待機し、オーバーラップした I/O 操作からのパケットを処理できます。

OpenMP* は、厳格な fork/join スレッド化モデルです。一部の OpenMP* の実装では、スレッドは並列領域の最初に作成され、並列領域の最後に破棄されます。OpenMP* アプリケーションには通常、干渉するシリアル領域と複数の並列領域があります。

特に並列領域がループの内部にある場合、各並列領域でスレッドの作成と破棄を行うと、大量のシステム・オーバーヘッドが発生します。このため、インテルでは、OpenMP* の実装にスレッドプールを使用しています。ワーカースレッドのプールは、最初の並列領域で作成されます。これらのスレッドは、プログラム実行中はずっと存在します。プログラムによって要求された場合、より多くのスレッドが自動的に追加されます。最後の並列領域が実行されるまで、スレッドは破棄されません。

スレッドプールは、スレッド作成 API を使用して Windows および Linux で作成できます。例えば、Win32 スレッドを使用するカスタム・スレッド・プールは、以下のように作成されます。

// Initialization method/function
{
  DWORD tid;
  // Create initial pool of threads
   for (int i = 0; i < MIN_THREADS; i++)
   {
    HANDLE *ThHandle = CreateThread (NULL,0,CheckPoolQueue,NULL,0,&tid);
    if (ThHandle == NULL)
    // Handle Error
    else
    RegisterPoolThread (ThHandle);
   }
}

プールの各スレッドによって実行される CheckPoolQueue() 関数は、作業がキューで利用可能になるまで、待機状態になるように設計されています。スレッド・マネージャーは、キューで待機状態のジョブを追跡し、需要に基づいてプールのスレッドの数を動的に増やします。


このヘルプトピックについてのフィードバックを送信

© 1996-2010 Intel Corporation. 無断での引用、転載を禁じます。