40

.Net で ThreadPool を使用してはいけない場合は?

最良のオプションは ThreadPool を使用することのようですが、その場合、それが唯一のオプションではないのはなぜですか?

これについてあなたの経験は何ですか?

4

9 に答える 9

30

@エリック、ディーンに同意する必要があります。スレッドは高価です。自分のプログラムだけが実行されていると想定することはできません。誰もがリソースに貪欲になると、問題は倍増します。

スレッドを手動で作成し、自分で制御することを好みます。これにより、コードが非常に理解しやすくなります。

適当な時でいいです。ただし、多数のワーカー スレッドが必要な場合は、コードをより複雑にするだけです。次に、それらを管理するコードを作成する必要があります。スレッド プールを使用しただけの場合は、すべてのスレッド管理を無料で利用できます。また、言語によって提供されるスレッド プールは、自分でロールするものよりも堅牢で効率的で、バグが少ない可能性が非常に高くなります。

Thread t = new Thread(new ThreadStart(DoSomething));  
t.Start();  
t.Join();  

Start()通常、 と の間に追加のコードがあることを願っていますJoin()。そうしないと、余分なスレッドは役に立たず、理由もなくリソースを浪費することになります。

人々は、スレッドが使用するリソースをあまりにも恐れています。スレッドの作成と開始に 1 ミリ秒以上かかるのを見たことがありません。作成できるスレッドの数に厳密な制限はありません。RAM の使用量は最小限です。スレッド数が数百になると、コンテキストの切り替えが原因で CPU が問題になるため、その時点で設計を工夫する必要があります。

最新のハードウェアでは、1 ミリ秒は長い時間です。これは、3 GHz マシンで 300 万サイクルです。繰り返しますが、スレッドを作成しているのはあなただけではありません。スレッドは、他のすべてのプログラムのスレッドと一緒に CPU をめぐって競合します。それほど多くないスレッドを使用し、別のプログラムも同様である場合、一緒に使用したスレッドが多すぎます。

真剣に、人生を必要以上に複雑にしないでください。それが提供する非常に具体的なものが必要でない限り、スレッドプールを使用しないでください。

それはそう。人生をより複雑にしないでください。プログラムに複数のワーカー スレッドが必要な場合は、車輪を再発明しないでください。スレッド プールを使用します。それがそこにある理由です。独自の文字列クラスを作成しますか?

于 2008-08-13T21:05:26.250 に答える
17

安価なマルチスレッドに を使用しない唯一の理由ThreadPoolは、必要がある場合です...

  1. 実行中のメソッドと対話する (たとえば、メソッドを強制終了する)
  2. STAスレッドでコードを実行します(これは私に起こりました)
  3. アプリケーションが停止した後もスレッドを維持する (ThreadPoolスレッドはバックグラウンド スレッドです)
  4. スレッドの優先度を変更する必要がある場合。デフォルトで Normal である ThreadPool 内のスレッドの優先度を変更することはできません。

PS: MSDN の記事「The Managed Thread Pool」には、 「When Not to Use Thread Pool Threads」というタイトルのセクションがあり、スレッド プールを使用しない考えられる理由について、非常によく似ていますが、より完全なリストが示されています。

をスキップする必要がある理由はたくさんありますが、ThreadPoolそれらがわからない場合は、 でThreadPool十分です。

または、新しいParallel Extensions FrameworkThreadPoolを見てください。.

于 2008-08-13T19:32:25.253 に答える
9

スレッド プールは、ワーカー スレッドの概念がある場合はいつでも意味があります。処理を小さなジョブに簡単に分割し、それぞれを個別に処理できる場合はいつでも、ワーカー スレッド (したがってスレッド プール) が適しています。

「ジョブ」と見なすことができない、まったく異なる、無関係なアクションを実行するスレッドが必要な場合、スレッドプールは意味がありません。たとえば、GUI イベント処理用に 1 つのスレッド、バックエンド処理用に別のスレッド。処理がパイプラインを形成する場合、スレッド プールも意味がありません。

基本的に、開始、ジョブの処理、および終了を行うスレッドがある場合は、スレッド プールを使用することをお勧めします。それ以外の場合、スレッド プールは実際には役に立ちません。

于 2008-08-13T19:32:16.267 に答える
9

口論者の答えとして、スレッドがすぐに機能することを保証する必要がある場合は、ThreadPool スレッドを使用しないことをお勧めします。実行中のスレッド プール スレッドの最大数はアプリ ドメインごとに制限されているため、すべてのスレッドがビジー状態の場合、作業を待たなければならない場合があります。結局、それは「キュー ユーザー ワーク アイテム」と呼ばれます。

もちろん、2 つの注意事項があります。

  1. 実行時にコード内のスレッド プール スレッドの最大数を変更できるため、現在の最大数と最大数をチェックし、必要に応じて最大数を増やすことを止めるものは何もありません。
  2. 新しいスレッドをスピンアップするには、それ自体に時間のペナルティが伴います。ヒットする価値があるかどうかは、状況によって異なります。
于 2008-08-13T19:34:29.273 に答える
2

私はここで理論的な知識だけを持っている人として話しているわけではありません。私は、マルチスレッドを多用する大量のアプリケーションを作成および保守していますが、通常、スレッド プールが正しい答えであるとは思いません。

ああ、当局からの議論ですが、Windows カーネル チームのメンバーである可能性がある人には常に注意してください。

特定の要件がある場合、.NET ThreadPool が適切ではない可能性があるという事実については、どちらも議論していません。私たちが反対しているのは、スレッドを作成するマシンのコストを矮小化することです。

そもそも ThreadPool の存在理由でスレッドを作成するための多大な費用。スレッドを作成する費用について誤った情報を与えられた人々によって記述されたコードでマシンがいっぱいになるのは望ましくありません。たとえば、スレッドを作成するたびにメソッドが呼び出されることを知りませんプロセスにアタッチされ(一部はサードパーティによって作成されます)、RAMにまったく存在する必要がなく、ほぼ確実にL1に存在する必要のないコードのロードをホットアップする可能性があります.

最新のマシンのメモリ階層の形状は、CPU の「気を散らす」ことは、あなたができる最悪のことであり、自分の技術を気にする人は誰でもそれを避けるために一生懸命働くべきであることを意味します。

于 2008-08-13T22:08:27.857 に答える
1

長時間かかる操作や、継続的なバックグラウンド スレッドを実行する場合。プールで使用可能なスレッドの量をいつでも押し上げることができると思いますが、プールに戻されることのないスレッドの管理コストを負担してもほとんど意味がありません。

于 2008-08-13T19:27:42.673 に答える
0

MSDN には、ここにいくつかの理由のリストがあります。

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

スレッド プール スレッドを使用する代わりに、独自のスレッドを作成して管理することが適切なシナリオがいくつかあります。

  • フォアグラウンド スレッドが必要です。
  • 特定の優先度を持つスレッドが必要です。
  • スレッドが長時間ブロックされる原因となるタスクがあります。スレッド プールには最大数のスレッドがあるため、多数のスレッド プール スレッドがブロックされると、タスクの開始が妨げられる可能性があります。
  • スレッドをシングルスレッド アパートメントに配置する必要があります。すべての ThreadPool スレッドはマルチスレッド アパートメントにあります。
  • スレッドに関連付けられた安定した ID を持つか、スレッドをタスク専用にする必要があります。
于 2012-08-13T04:45:32.770 に答える
-1

@エリック

@Derek、例として使用するシナリオにはまったく同意しません。マシンで何が実行されているか、アプリが特定の負荷の下で使用するスレッド、ハンドル、CPU 時間、RAM などの合計数が正確にわからない場合は、問題が発生します。

あなたが書いたプログラムのターゲット顧客はあなただけですか? そうでない場合、そのほとんどについて確信を持てません。通常、プログラムを作成するときに、それが単独で効果的に実行されるのか、それとも DDOS 攻撃によって攻撃された Web サーバー上で実行されるのかはわかりません。どのくらいの CPU 時間を使用するかはわかりません。

入力に基づいてプログラムの動作が変化すると仮定すると、プログラムが消費するメモリや CPU 時間を正確に知ることさえほとんどできません。確かに、プログラムがどのように動作するかについてかなり良い考えを持っている必要がありますが、完全な分析にはコストがかかるため、ほとんどのプログラムは、使用されるメモリ量やハンドル数などを正確に決定するために分析されることはありません。リアルタイム ソフトウェアを作成していない場合、その見返りは努力に見合うものではありません。

一般に、プログラムがどのように動作するかを正確に知っていると主張することは、とてつもないことであり、マシンに関するすべてを知っていると主張することはばかげています。

正直なところ、手動​​スレッド、スレッド プール、デリゲート、およびアプリケーションが必要とすることを実行するための実装方法など、どの方法を使用する必要があるかを正確に把握していないと、問題が発生します。

私は完全に同意しませんが、それがどのように関連しているかはよくわかりません. このサイトがここにあるのは、プログラマーが常にすべての答えを持っているとは限らないためです。

アプリケーションが複雑で、使用するスレッドの数を調整する必要がある場合、ほとんどの場合、フレームワークが提供する以上の制御が必要になるのではないでしょうか?

いいえ。スレッド プールが必要な場合は、十分でないことが判明しない限り、提供されているものを使用します。提供されたスレッド プールが私のニーズに対して不十分であると単純に仮定するつもりはありません。

私はここで理論的な知識だけを持っている人として話しているわけではありません。私は、マルチスレッドを多用する大量のアプリケーションを作成および保守していますが、通常、スレッド プールが正しい答えであるとは思いません。

私の専門的な経験のほとんどは、マルチスレッドおよびマルチプロセッシング プログラムに関するものです。私も自分のソリューションを展開する必要があることがよくありました。これは、スレッド プールが役に立たない、または多くの場合に適切でないという意味ではありません。スレッド プールは、ワーカー スレッドを処理するように構築されています。複数のワーカー スレッドが適切な場合は、通常、提供されたスレッド プールを最初のアプローチにする必要があります。

于 2008-08-13T22:05:27.050 に答える