スレッド プール

イベントの発生を待機しているスリープ状態で多くの時間を費やすスレッドを作成するアプリケーションは多数あります。 他のスレッドは、変更または更新の状態情報をポーリングするために定期的に起動されるためだけにスリープ状態になる場合があります。 スレッド プールを 使用すると、システムによって管理されるワーカー スレッドのプールをアプリケーションに提供することで、スレッドをより効率的に使用できます。 少なくとも 1 つのスレッドが、スレッド プールにキューに登録されているすべての待機操作の状態を監視します。 待機操作が完了すると、スレッド プールのワーカー スレッドが対応するコールバック関数を実行します。

このトピックでは、元のスレッド プール API について説明します。 Windows Vista で導入されたスレッド プール API は、よりシンプルで信頼性が高く、パフォーマンスが向上し、開発者にとって柔軟性が高くなります。 現在のスレッド プール API の詳細については、「 スレッド プール」を参照してください。

待機操作に関連しない作業項目をスレッド プールにキューに入れることもできます。 スレッド プール内のスレッドによって作業項目が処理されるように要求するには、 QueueUserWorkItem 関数を呼び出します。 この関数は、スレッド プールから選択されたスレッドによって呼び出される関数にパラメーターを受け取ります。 作業項目がキューに入った後に取り消す方法はありません。

タイマー キュー タイマー登録済み待機操作 では、スレッド プールも使用されます。 コールバック関数はスレッド プールにキューに入れられます。 BindIoCompletionCallback 関数を使用して、非同期 I/O 操作をポストすることもできます。 I/O が完了すると、コールバックはスレッド プール スレッドによって実行されます。

スレッド プールは、 QueueUserWorkItem または BindIoCompletionCallback を初めて呼び出すとき、またはタイマー キュー タイマーまたは登録済み待機操作がコールバック関数をキューに入れたときに作成されます。 既定では、スレッド プールに作成できるスレッドの数は約 500 です。 各スレッドは既定のスタック サイズを使用し、既定の優先順位で実行されます。

スレッド プールには、I/O と I/O 以外の 2 種類のワーカー スレッドがあります。 I/O ワーカー スレッドは、アラート可能な待機状態で待機するスレッドです。 作業項目は、非同期プロシージャ呼び出し (APC) として I/O ワーカー スレッドにキューに入れられます。 作業項目を警告可能な状態で待機するスレッドで実行する必要がある場合は、作業項目を I/O ワーカー スレッドにキューに入れる必要があります。

I/O 以外のワーカー スレッドは、I/O 完了ポートで待機します。 I/O 以外のワーカー スレッドを使用する方が、I/O ワーカー スレッドを使用するよりも効率的です。 そのため、可能な限り I/O 以外のワーカー スレッドを使用する必要があります。 保留中の非同期 I/O 要求がある場合、I/O ワーカー スレッドと I/O 以外のワーカー スレッドの両方が終了しません。 どちらの種類のスレッドも、非同期 I/O 完了要求を開始する作業項目で使用できます。 ただし、完了に時間がかかる可能性がある場合は、I/O 以外のワーカー スレッドに非同期 I/O 完了要求を投稿しないようにします。

スレッド プールを使用するには、作業項目と、呼び出すすべての関数がスレッド プール セーフである必要があります。 セーフ関数は、それを実行しているスレッドが専用または永続的なスレッドであるとは想定しません。 一般に、 スレッド ローカル ストレージ を使用したり、 RegNotifyChangeKeyValue 関数などの永続的なスレッドを必要とする非同期呼び出しを行ったりしないようにする必要があります。 ただし、このような関数は、(アプリケーションによって作成された) 専用スレッドで呼び出したり、永続的なワーカー スレッド (WT_EXECUTEINPERSISTENTTHREAD オプションと共に QueueUserWorkItem を使用) にキューに入れたりすることができます。

アラート可能な I/O

非同期プロシージャ呼び出し

I/O 完了ポート

スレッド プール