0

QueueUserWorkItem()関数を使用してスレッドプールを呼び出します。
そして、私はそれでたくさんの仕事を試みました。(約30000)
しかし、タスクマネージャーによって、私のアプリケーションは、スタートボタンを押した後にのみ4〜5スレッドを作成します。
スレッド制限のデフォルト数は約500であると述べたMSDNを読みました。
なぜ、アプリケーションでスレッドの数が少ないのですか?
私は自分のアプリケーションを高速化するのに疲れています。このスレッドプールが私のアプリケーションを遅くする理由の1つだと思います。

ありがとう

4

3 に答える 3

1

スレッドプールの使い方を誤解しているのではないかと思います。スレッドの生成とスレッドの強制終了にはWindowsカーネルが関係しており、コストのかかる操作です。非同期操作を実行するためにスレッドが継続的に必要な場合、それらを破棄すると、多くのシステムコールが実行されます。

したがって、スレッドプールは実際には一度作成されたスレッドのグループであり、タスクの完了時に終了するのではなく、実際にqueueuserworkitemの別のアイテムの待機に入ります。スレッドプールは、プロセスに同時に必要なスレッドの数に基づいて、それ自体を調整します。これをテストしたい場合は、次のコードを記述してください。

for(int i = 0; i < 30000; i++)
{
    ThreadPool.QueueUserWorkItem(myMethod);
}

これにより、多数のスレッドが作成されることがわかります。ThreadPoolが関数呼び出しを処理し始めるときに、作成されたスレッドの一部が再利用されるため、おそらく30000ではありません。

于 2010-01-10T11:00:10.763 に答える
1

スレッドプールスケジューラがどのように機能するかを理解することが重要です。これは、マシンの機能に対して実行中のスレッドの数を微調整するように設計されています。お使いのマシンはおそらく同時に2つのスレッドしか実行できません。現在、デュアルコアCPUが標準です。多分4つ。

したがって、ラップに多数のスレッドをダンプすると、2つのスレッドのみをアクティブ化することから始まります。それらの残りはキューにあり、CPUコアが使用可能になるのを待っています。これらの2つのスレッドの1つが完了するとすぐに、別のスレッドがアクティブになります。1秒に2回、完了しなかったアクティブなスレッドで何が起こっているかを評価します。これは、これらのスレッドがブロックされているために進行しておらず、別のスレッドがアクティブ化できることを大まかに想定しています。これで、3つの実行中のスレッドができました。デフォルトの最大スレッド数である500スレッドを取得するには、249秒かかります。

明らかに、この動作は、スレッドがスレッドプールスレッドとして実行するのに適しているために何をすべきかを詳しく説明しています。すぐに完了し、頻繁にブロックしないようにする必要があります。I/O要求のブロックは個別に処理されることに注意してください。

この動作が適切でない場合は、通常のスレッドを使用できます。すぐに実行を開始し、CPU時間についてプログラム(およびオペレーティングシステム)内の他のスレッドと競合します。このようなスレッドを30,000個作成することはできません。そのために使用できる、十分な仮想メモリがありません。32ビットオペレーティングシステムは、2000スレッドの南のどこかでうんちを出し、使用可能なすべての仮想メモリを消費します。ページングファイルがなくなる前に、64ビットオペレーティングシステムで約50,000スレッドを取得できます。本番プログラムでこれらの制限をテストすることはお勧めしません。

于 2010-01-10T13:12:51.853 に答える
0

スレッドプールが存在するため、スレッドが高価であるという理由から、非同期操作ごとにスレッドを作成することを回避できます。30,000スレッドが必要な場合は、スレッドスタックに大量のメモリを使用し、コンテキストスイッチを実行するために多くのCPU時間を浪費します。30,000個のCPUコアがある場合、その数のスレッドを作成することは正当化されます...

于 2010-01-10T10:54:37.077 に答える