2

CreateIoCompletionPortの同時スレッド数に対して選択された回答に関連して、I/O完了ポートのドキュメントの「実行可能なスレッド」の定義について質問があります。

完了ポートに関連付けられた実行可能スレッドの総数が同時実行値に達すると、実行可能スレッドの数が同時実行値を下回るまで、システムはその完了ポートに関連付けられた後続のスレッドの実行をブロックします。

GetQueuedCompletionStatus()完了パケットが投稿されたためにウェイクアップされたスレッドは、他の理由でスリープ状態になる可能性があることを理解しています(つまり、まだジョブを完了しておらず、呼び出しGetQueuedCompletionStatus()に戻っていないが、スリープしているため、正しく理解する-上記の定義に従って実行することはできません)

私が特に知りたいのはこれです:上記のスレッドが処理中に、別のスレッドを生成し、その別のスレッドが完了するのを待っているためにスリープしていると仮定しますか?

子スレッドが実行可能状態にある場合、スレッドは「実行可能」状態にあると見なされますか?

そうでない場合、実行中のスレッドの総数がを超えるなど、他のスレッドがウェイクアップする危険を冒さずに、完了ポートに関連付けられたスレッドからワーカースレッドを生成できないようですNumberOfConcurrentThreads

たとえば、50のスレッドが待機していてGetQueuedCompletionStatus()、同時スレッドの数が5であるとすると、非常に長いタスクをトリガーする20の完了パケットが同時に送信され、スレッドがこれらのタスクの1つを実行するためにウェイクアップするたびに、すぐに1つの新しいスレッドが生成されます。スレッドが作業を実行し、そのスレッドが長いタスクを完了するのを待ってから、GetQueuedCompletionStatus()もう一度呼び出しに戻ります。

この例では、20個のスレッドがウェイクアップして、並行して動作する合計20個の子スレッドを生成しますか、それとも5個のスレッドだけですか?

(注:補遺:私は特定のケースでBoost.Asioを使用してワーカースレッドのプールを実装しています-これは内部でI / O完了ポートを利用します-そして私のワーカースレッドはJNIを使​​用してJavaを呼び出します;内部では、Javaコードは独自のものを生成しますワーカースレッド-これが私に関係することです。)

4

1 に答える 1

1

このような質問に対する答えを探す場所は、常にJeffreyRichterとChristopheNasarreによる「WindowsViaC / C ++(PRO-Developer) 」です。

私のコピーの327ページでは、I / O完了ポートが、呼び出しから解放されたスレッド(または同等のもの)のスレッドIDを追跡し、GetQueuedCompletionStatus()それらのスレッドが呼び出されない限り、それらのスレッドを「実行中」としてカウントすることを明確に説明しています。それらを待機状態にする関数。

したがって、この例では、呼び出し元のスレッドがJNIによって作成されたスレッドを待機していると仮定すると、GetQueuedCompletionStatus()そのスレッドは「実行されていない」と見なされるため、IOCPは別のスレッドGetQueuedCompletionStatus()をサービス要求から解放できます。すべてのスレッドが最終的にJNIを呼び出して別のスレッドを作成する場合は、基本的にスケーリングに失敗する可能性のある「イベントごとのスレッド」デザインと、スケーリングに失敗するIOCPデザインを作成しているため、デザインに問題があると思います。外部スレッドを作成しないでください...

スレッドを生成するのはJNIレイヤーの機能ですか、それとも呼び出しているJavaコードに純粋に含まれていますか?後である場合は、可能であればJavaコードを再設計することをお勧めします...

于 2012-11-17T17:27:11.407 に答える