147

新しいスレッドを使用することと、スレッド プールからスレッドを使用することの違いは何ですか? 明示的に作成したスレッドではなく、プールからのスレッドの使用を検討する必要があるのはなぜですか? ここでは特に .NET について考えていますが、一般的な例で問題ありません。

4

11 に答える 11

119

スレッドプールは、頻繁で比較的短い操作に対して利点を提供します。

  • 新しいスレッドを作成する代わりに、すでに作成されているスレッドを再利用する (コストのかかるプロセス)
  • 新しい作業項目の要求が急増したときにスレッド作成の速度を調整する (これは .NET 3.5 のみにあると思います)
    • 100 個のスレッド プール タスクをキューに入れると、これらの要求を処理するために既に作成されている数 (たとえば 10 個) のスレッドのみが使用されます。スレッド プールは頻繁にチェックを行い (3.5 SP1 では 500 ミリ秒ごとだと思います)、キューに入れられたタスクがある場合は、新しいスレッドを 1 つ作成します。タスクが高速な場合、新しいスレッドの数は少なくなり、短いタスクに 10 程度のスレッドを再利用する方が、事前に 100 のスレッドを作成するよりも高速になります。

    • ワークロードに大量のスレッド プール リクエストが常に入ってくる場合、スレッド プールは、上記のプロセスによってプール内により多くのスレッドを作成することでワークロードに合わせて調整し、リクエストの処理に使用できるスレッドの数を増やします。

    • 内部でスレッドプールがどのように機能するかについての詳細は、こちらを確認してください

ジョブが比較的長時間実行される場合は、自分で新しいスレッドを作成する方が適切です (おそらく 1 ~ 2 秒程度ですが、特定の状況によって異なります)。

@Krzysztof - スレッド プール スレッドは、メイン スレッドが終了すると停止するバックグラウンド スレッドです。手動で作成されたスレッドは、既定ではフォアグラウンド (メイン スレッドが終了した後も実行され続けます) ですが、Start を呼び出す前にバックグラウンドに設定できます。

于 2008-10-23T14:48:06.343 に答える
16

.NET マネージ スレッドプール: -

  • 現在のワークロードと利用可能なハードウェアに基づいてサイズを調整します
  • ワーカー スレッド完了ポート スレッド (特に IO を処理するために使用される) が含まれています。
  • 多数の比較的短期間の操作用に最適化されている

長時間実行される操作により適した他のスレッド プール実装が存在します。

具体的には、スレッド プールを使用して、アプリが作成するスレッドが多すぎるのを防ぎます。スレッドプールの最も重要な機能は作業キューです。つまり、マシンが十分にビジー状態になると、スレッドプールはすぐにより多くのスレッドを生成するのではなく、要求をキューに入れます。

そのため、限られた数のスレッドを作成する場合は、自分で作成してください。作成される可能性のあるスレッドの数を前もって判断できず (たとえば、着信 IO に応答して作成される)、それらの作業が短期間で終了する場合は、スレッドプールを使用してください。いくつかわからないが、彼らの作業が長期にわたる場合、プラットフォームには何も役に立ちませんが、適切な代替スレッドプール実装を見つけることができるかもしれません.

于 2008-10-23T14:56:59.570 に答える
13

また

new Thread().Start()

プログラムを閉じても死なないフォアグラウンド スレッドを生成します。ThreadPool スレッドは、アプリを閉じると終了するバックグラウンド スレッドです。

于 2008-10-23T14:52:26.523 に答える
10

私はこれらの相対的なリソース使用量に興味があり、Windows 8 で .net 4.0 リリース ビルドを使用して 2012 デュアルコア Intel i5 ラップトップでベンチマークを実行しました。 MS。つまり、プール内のスレッドは、存続期間の短いスレッドが多数ある場合、約 300 倍速く開始されました。少なくともテストされた範囲 (100 ~ 2000 スレッド) では、スレッドあたりの合計時間はかなり一定しているように見えました。

これは、ベンチマークされたコードです。

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

ここに画像の説明を入力

于 2016-02-01T06:56:09.230 に答える
5

以前のスレッドについては、ここを確認してください。

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

要約すると、存続期間の短いスレッドを多数生成する必要がある場合は、Threadpool が適していますが、Threads を使用すると、より詳細な制御が可能になります。

于 2008-10-23T14:48:31.040 に答える
3

多くのスレッドが必要な場合は、おそらく ThreadPool を使用することをお勧めします。スレッドを再利用するため、スレッド作成のオーバーヘッドを節約できます。

何かを行うのに 1 つのスレッドだけが必要な場合は、おそらく Thread が最も簡単です。

于 2008-10-23T14:50:09.227 に答える
2

adpool スレッドの主な必要性は、ほぼ瞬時に完了すると予想される短い小さなタスクを処理することです。ハードウェア割り込みハンドラーは、多くの場合、非カーネル コードには適していないスタッキング コンテキストで実行されますが、ハードウェア割り込みハンドラーは、ユーザー モード I/O 完了コールバックをできるだけ早く実行する必要があることを検出する場合があります。そのようなことを実行する目的で新しいスレッドを作成するのは、非常にやり過ぎです。I/O 完了コールバックやその他の同様のものを実行するためにディスパッチできるいくつかの事前作成されたスレッドがあると、はるかに効率的です。

このようなスレッドの重要な側面は、I/O 完了メソッドが常に本質的に瞬時に完了し、ブロックされることがなく、現在そのようなメソッドを実行しているスレッドの数がプロセッサの数と少なくとも等しい場合、他のスレッドが唯一の方法であるということです。前述のメソッドのいずれかが終了する前に実行される可能性があるのは、他のメソッドのいずれかがブロックされるか、その実行時間が通常のスレッド タイム スライスを超える場合です。スレッドプールが意図したとおりに使用されている場合、これらのいずれも頻繁に発生することはありません。

メソッドが実行を開始してから 100 ミリ秒以内に終了することが期待できない場合は、メイン スレッド プール以外の方法でメソッドを実行する必要があります。CPU を集中的に使用するがブロックされない実行するタスクが多数ある場合は、「メイン」スレッドプールとは別のアプリケーション スレッドのプール (CPU コアごとに 1 つ) を使用してそれらをディスパッチすると役立つ場合があります。非ブロッキングの CPU 集中型タスクを実行する場合、コアよりも多くのスレッドは逆効果になります。ただし、メソッドの実行に 1 秒以上かかり、ほとんどの時間をブロックされる場合は、そのメソッドを専用スレッドで実行する必要があり、ほとんどの場合、メイン スレッドプール スレッドで実行しないでください。I/O コールバックなどによって長時間実行される操作をトリガーする必要がある場合は、

于 2015-02-21T21:25:34.993 に答える
2

スレッド ローカル ストレージは、スレッド プールではお勧めできません。スレッドに「アイデンティティ」を与えます。すべてのスレッドが等しいわけではありません。現在、スレッド プールは、作成オーバーヘッドなしで作業を行う準備ができている同一のスレッドの束が必要な場合に特に便利です。

于 2008-10-23T14:46:50.620 に答える
1

一般に (私は .NET を使用したことがありません)、スレッド プールはリソース管理の目的で使用されます。ソフトウェアに制約を設定できます。また、新しいスレッドの作成にはコストがかかる可能性があるため、パフォーマンス上の理由から行うこともできます。

システム固有の理由も考えられます。Java では (これが .NET に適用されるかどうかはわかりません)、スレッドのマネージャーは、各スレッドがプールから引き出されるときにスレッド固有の変数を適用し、それらが返されたときに設定を解除することができます (次のようなものを渡す一般的な方法)アイデンティティ)。

制約の例: db 接続は 10 個しかないので、データベースへのアクセスには 10 個のワーカー スレッドしか許可しません。

これは、独自のスレッドを作成してはならないという意味ではありませんが、プールを使用する意味がある条件があります。

于 2008-10-23T14:54:29.310 に答える
0

作成されるスレッドの数がわからない、または制御できない場合は、プールを使用することをお勧めします。

リストコントロールのイベントでスレッドを使用してデータベースからいくつかのフィールドを更新するフォームに問題がありますpositionchanged(フリーズを回避します)。ユーザーがリストの位置を変更するのが速すぎたため、データベースからのエラー (Access との接続が多すぎる) が発生するまでに 5 分かかりました...

基本的な問題 (アクセスを使用しないことを含む) を解決する他の方法があることは知っていますが、プーリングは良い出発点です。

于 2014-01-08T16:58:31.893 に答える