26

ThreadPoolスレッドまたは TPL Taskの優先順位を変更することを思いとどまらせる Web およびスタック オーバーフローの多くの場所があります。特に:

「スレッド プール スレッドの状態と優先度を制御することはできません。」
「ランタイムはスレッド プールを管理します。スレッドのスケジューリングを制御することも、スレッドの優先度を変更することもできません。」

「PoolThread の Culture や Priority などを変更するべきではありません。レンタカーを塗装したり再装飾したりしないのと同じです。」

「スレッド プール スレッドを使用する代わりに、独自のスレッドを作成して管理することが適切なシナリオがいくつかあります: (など...) スレッドに特定の優先度が必要です。」

「ThreadPool の各スレッドはデフォルトの優先度で実行され、ThreadPriority を変更するコードは効果がありません。」

ただし、そうするのは簡単なことであり、デバッガーは、値が読み取れる限り、変更が固定されているように見えることを示しています。

Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;

問題は、この特定のタブーの具体的な理由は何ですか?

私の疑い: そうすることで、プールのデリケートな負荷分散の仮定が妨げられます。しかし、これは、一部のソースが変更できないと言う理由を説明していません.

4

6 に答える 6

22

スレッド プール、特に .NET 4.0 スレッド プールには多くのトリックが用意されており、かなり複雑なシステムです。タスクとタスク スケジューラを追加し、ワーク スティーリングやその他のあらゆる種類のものを追加すると、実際には何が起こっているのかわかりません。スレッド プールは、タスクが I/O で待機していることに気づき、タスクで何かをすばやくスケジュールするか、スレッドを一時停止して優先度の高いものを実行するかを決定する場合があります。あなたのスレッドは、どういうわけか優先順位の高いスレッド (あなたが気づいているかもしれないし、気づいていないかもしれません) への依存関係であり、最終的にデッドロックを引き起こす可能性があります。スレッドが何らかの異常な方法で終了し、優先度を回復できない可能性があります。

スレッドの優先度を低くすることが最善であると考えるような長時間実行されるタスクがある場合、スレッド プールはおそらく適切ではありません。アルゴリズムは .NET 4.0 で改善されましたが、新しいスレッドを作成するコストがタスクの長さに不釣り合いな短期間のタスクに使用するのに最適です。タスクが 1 秒または 2 秒以上実行される場合、新しいスレッドを作成するコストは取るに足らないものです (ただし、管理は煩わしいかもしれません)。

于 2011-04-08T01:22:07.843 に答える
9

サイズを縮小したスレッド プールでいくつかの実験を行いました。これは、スレッドの優先度がプールに戻されると通常にリセットされることを示しているようです。スレッドに関するこのリソースはそれを確認しているようです。そのため、行っても効果は非常に限られているようです。

于 2011-05-13T00:05:00.210 に答える
2

優先度を下げると、予期しない結果が生じる可能性もあります。

アプリケーションでタスクをスケジュールするだけでなく、他のいくつかのタスクをスケジュールするライブラリも呼び出すとします。アプリ タスクの実行中にスレッドの優先度を下げたとします。その後、プールが多くのスレッドを生成しない場合、優先度の低いタスクが終了するのを待っているライブラリ内の通常の優先度のタスクで終わる可能性がありますが、優先度の低いスレッドには、残りのスレッドの場合、多くの CPU 時間が与えられない可能性があります。システムには、実行したい標準優先度のスレッドが多数あります。

プール スレッドの数を増やすと、これが軽減されますが、スタックでより多くのメモリが浪費され、コンテキスト スイッチにより多くの CPU 時間が費やされます。

于 2011-12-19T17:37:47.517 に答える
0

何かを変更する場合は、try / finalを使用して、見つけたままにしておくようにしてください。

于 2011-04-08T09:07:15.150 に答える
0

システムの全体的なパフォーマンスに影響を与える可能性があるため、特に優先度を上げる場合はお勧めできません。

過度に複雑な回答を提供するつもりはありませんが、一般に、スレッドの優先度は複雑なトピックです。たとえば、Windows には、スレッドの優先度とプロセスの優先度という 2 つの関連する記述子があります。どちらも、最小のアイドルから最高のタイム クリティカルまでの範囲です。新しいプロセスを開始すると、デフォルトの中間範囲 (通常のプロセス優先度と通常のスレッド優先度) に設定されます。

さらに、スレッドの優先度は相対的です。つまり、忙しいシステムでスレッドの優先度を最高に設定しても、「リアルタイム」で実行されることは保証されません。DotNET はこれについて保証を提供しません。Windows も保証しません。このことから、99.9% の確率でスレッドプールが最もよく知っているため、スレッドプールをそのままにしておく方がよい理由がわかります :)

とはいえ、タスクに長い計算が含まれる場合は、スレッドの優先度を下げても問題ありません。これは他のプロセスには影響しません。

ただし、優先度を上げることは、他のプロセスに悪影響を及ぼす可能性があるため、迅速に対応する必要があり、実行時間が短いタスクに対してのみ行う必要があります。

于 2011-05-13T00:49:20.377 に答える
0

本当に必要に応じて変更することはできますが、スレッド プールのスレッドが再利用されると、実行される次のコードで変更が予期されない可能性があります。

于 2011-04-08T01:11:54.727 に答える