web-dev-qa-db-ja.com

ThreadPoolの最大スレッド数

.NETのThreadPool(.NET 4)で問題が発生しました。

デフォルトでは、.NETにはプロセッサあたり25スレッドの制限がありますが、フォーラムの投稿によると、SOおよび他の場所では、以下のコードで制限を増やすことができます。

_void SetThreads(int threads)
{
    ThreadPool.SetMaxThreads(threads, threads);
    ThreadPool.SetMinThreads(threads, threads);
}
_

ただし、上記を任意の高い数値(2000など)に設定し、〜1000アイテムをキューに入れると、〜33スレッドしか実行されません(.NET CLRは〜5スレッドを使用します)、およびThreadPool.GetAvailableThreads()残りの1971スレッドを返します。

上記のコードが機能しないのはなぜですか?

25
foxy

MSDNから

需要が低い場合、スレッドプールスレッドの実際の数が最小値を下回る可能性があります。

こちらもお読みください: 並列プログラミングのパターン:.NET Framework 4での並列パターンの理解と適用

8
Erno de Weerd

まず、デフォルトの「知識」が間違っています。プロセッサあたり25スレッドという制限は、.NET 1.1から戻っていました。 .NET 2で増加しました そして今

.NET Frameworkバージョン4以降、プロセスのスレッドプールのデフォルトサイズは、仮想アドレススペースのサイズなど、いくつかの要因に依存します。プロセスは、GetMaxThreadsメソッドを呼び出してスレッドの数を決定できます。

ただし、他にも何かがあります:スレッドプールは、すべての状況で新しいスレッドをすぐに作成しません。小さなタスクのバーストに対処するために、新しいスレッドを作成する速度を制限します。 IIRCは、未処理のタスクがある場合、最大スレッド数まで、0.5秒ごとに1つのスレッドを作成します。しかし、その図が文書化されているのをすぐに見ることはできません。私はそれがあなたが見ているものだと強く疑います。多数のアイテムをキューに入れてから、時間の経過とともにスレッドの数を監視してください。

81
Jon Skeet

まず、 このリンク 、特にこのコメントを確認してください:

インターネットインフォメーションサービス(IIS)またはSQL Serverなどによって共通言語ランタイムがホストされている場合、ホストはスレッドプールサイズの変更を制限または防止できます。

次に、ThreadPool.SetMaxThreads(threads, threads)メソッドの戻り値を確認する必要があります。多分それはfalseを返しますか?

2
Grook