24

ThreadPoolの動作方法についての私の理解が正しければ、その目的の1つは、特定の時間に作成できるプロセス内のワーカースレッドの数を制限することです。たとえば、MaxThreadsを5に設定してからQueueUserWorkItemを30回呼び出すと、ThreadPoolに対して30のリクエストが作成されますが、これらのリクエストのうち5つだけが新しいスレッドによって処理され、残りの25のリクエストはキューに追加されます。以前のリクエストが完了し、既存のスレッドが利用可能になると、一度に1つずつサービスが提供されます。

ただし、以下のコードでは、Thread.Sleep(-1)を呼び出すと、DoSomething()メソッドが返されないことが保証されます。つまり、現在のスレッドが後続のリクエストで使用できるようになることはありません。

しかし、ThreadPoolがどのように機能するかについての私の理解は正しくありません。なぜなら、それが正しければ、以下のコードは0〜29ではなく0〜4の数字のみを出力するからです。

誰かがThreadPoolがどのように機能するのか、そしてなぜ以下のコードが私が思っていたように動作しないのか説明してもらえますか?

    static void DoSomething(object n)
    {
        Console.WriteLine(n);
        Thread.Sleep(-1);
    }

    static void Main(string[] args)
    {
        ThreadPool.SetMaxThreads(5, 5);
        for (int x = 0; x < 30; x++)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), x);
        }
        Console.Read();
    }
4

4 に答える 4

18

ThreadPool.SetMaxThreads(5, 5)

アクティブなスレッドの数が5であることを意味します(5つ以上のCPUコアがある場合)。これは、ThreadPoolが5つのスレッドしか作成できないことを意味するものではありません。ThreadPoolの最大スレッド数=CPUコア*250。

以降Thread.Sleep、スレッドは非アクティブになるため、他のスレッドの実行には影響しません。

于 2013-01-25T05:35:45.030 に答える
4

しかし、ThreadPoolがどのように機能するかについての私の理解は正しくありません。なぜなら、それが正しければ、以下のコードは0〜29ではなく0〜4の数字のみを出力するからです。

はい、あなたの仮定は非常に正しいです。

uはThreadPoolに30個のジョブをキューに入れ、ジョブはInfiniteTimeの間スリープするため、終了することはありません。ThreadPoolクラスは、新しいスレッドを作成するために一定の間隔を待機しますが、スレッドの最大数を超えることはありません。

ノート

Console.Read()は、バックグラウンドスレッドを存続させています。

記事

MSDNから

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


すべてのスレッドプールスレッドがタスクに割り当てられている場合、スレッドプールはすぐに新しいアイドルスレッドの作成を開始しません。スレッドにスタックスペースを不必要に割り当てることを避けるために、間隔を置いて新しいアイドルスレッドを作成します。間隔は現在0.5秒ですが、.NETFrameworkの将来のバージョンで変更される可能性があります。


管理対象スレッドプール内のスレッドはバックグラウンドスレッドです。つまり、それらのIsBackgroundプロパティはtrueです。これは、すべてのフォアグラウンドスレッドが終了した後、ThreadPoolスレッドがアプリケーションの実行を維持しないことを意味します。

于 2013-01-25T05:36:48.733 に答える
2

Thread.Sleep(-1)が期待どおりに動作していない可能性があります。

パラメータInt32:スレッドがブロックされるミリ秒数。ゼロ(0)を指定して、このスレッドを一時停止して、他の待機中のスレッドを実行できるようにする必要があることを示します。スレッドを無期限にブロックするには、Infiniteを指定します。

http://msdn.microsoft.com/en-us/library/d00bd51t.aspx

タスクを調べる必要があります。http: //msdn.microsoft.com/en-us/library/dd235608.aspxスレッドプール2.0と考えてください。

于 2013-01-25T04:24:25.523 に答える
0

通常、ThreadPoolは、CPUコアの数と同じ数のスレッドを作成します。一度に1つのスレッドしかコアで処理できないため、スレッドをさらに作成する必要はありません。ただし、ThreadPoolにキューに入れられたタスクの実行に0.5秒以上かかる場合、ThreadPoolは、キュー内の残りのタスクを処理するための追加のスレッドを作成します。したがって、多くの重いタスクをThreadPoolにキューに入れると、マルチタスクをエミュレートし、すべてのタスクを「並列」で実行するための多くの追加スレッドが作成されます。ただし、合計実行時間は、追加のスレッドがない場合と同じになります。さらに、スレッドの作成は非常に重い操作であるため、さらに短くなります。そのため、小さなタスクにはThreadPoolをお勧めします。これは、実際には何の利点ももたらさない追加のスレッドの作成を回避するためです。

ThreadPoolの詳細については、Albahariの記事をご覧ください。実際、彼はスレッドに関する優れた記事を持っています。

于 2013-01-25T04:29:48.570 に答える