2

ジョブ キュー内のアイテムの for ループから ThreadPool.QueueUserWorkItem() API を使用してファイル コピー操作を実行するために複数のスレッドを生成する状況があります。ジョブ キューには約 50 個のアイテムが含まれています (テスト目的で使用)。

私たちは最大数を期待していました。処理のために 50 のスレッドが生成されるか、システムが (より高い作業負荷を使用して) 多くのスレッドを確保できない場合はさらに少なくなります。しかし、私たちがノーを印刷したとき。ThreadPool.GetAvailableThreads(out _iWorkerThreads, out _ioThreads) を使用してプール内の使用可能なスレッドを取得すると、定数 1023 (ワーカー スレッドのジョブ サイズ 50 の場合) が取得され、I/O スレッドのデータは取得されません。

非常に多くのスレッドが生成される理由がわかりません。ThreadPool.GetAvailableThreads からの出力は信頼できますか? スレッド プールの最大スレッド数を設定すると役に立ちますか? 平均数を評価する信頼できる方法は何ですか。プールからのプロセスによって使用されているマネージド スレッドの数は?

アプリの実行中に CPU 使用率がほぼ 100% に急上昇する理由を教えてください。このコードは、ジョブの完了をメイン スレッドに通知するために、各ジョブに添付された WaitHandles (通常は ManualResetEvent) を使用します。

4

1 に答える 1

4

それは生成されたスレッドの数ではありません。これは、最大数に達する前に生成できる追加のスレッドの数です。

MSDN: ThreadPool.GetAvailableThreads メソッド

GetMaxThreads から GetAvailableThreads を引いた数が、おそらく探している数値です。

何もせずに:

class Program
{
    static void Main(string[] args) {
        int workerThreads, completionPortThreads;
        ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
        Console.WriteLine(workerThreads);
        Console.WriteLine(completionPortThreads);
        Console.ReadLine();
    }
}

出力は次のとおりです。

1023
1000

一部のスレッドがまだ動作していることがわかっているときに ThreadPool.GetAvailableThreads を呼び出すようにすると、数値が低くなるはずです。

例:

    static void Main(string[] args) {
        int workerThreads, completionPortThreads;
        ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
        Console.WriteLine(workerThreads);
        Console.WriteLine(completionPortThreads);

        Console.WriteLine();
        ThreadPool.QueueUserWorkItem(o => Thread.Sleep(10000));

        ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
        Console.WriteLine(workerThreads);
        Console.WriteLine(completionPortThreads);

        Console.ReadLine();
    }

出力は次のとおりです。

1023
1000

1022
1000
于 2012-08-23T19:38:21.667 に答える