2

あるスレッドがリンクリストに書き込み、別のスレッドがリンクリストを処理することで、処理を高速化しようとしています。

何らかの理由で、リンクリストに書き込むメソッドをタスクにし、リンクリストから優先度の低いスレッドを読み取るメソッドを使用すると、プログラムは全体としてはるかに高速に終了します。言い換えれば、私は次のことを行うときに最速の結果を経験します。

 Task.Factory.StartNew( AddItems );

 new Thread( startProcessingItems ) { Priority = ThreadPriority.Lowest }.Start();

 while(completed==false)
    Thread.Sleep(0);

おそらく、最初のタスクが他のスレッドよりも多くの余分な作業を行っているため、2番目のメソッドの優先度を低く設定すると、全体としてすべてがより速く終了します。

とにかく今私の質問はstartProcessingItemsThreadPriority=Lowestでの実行です。優先度を最高に変更するにはどうすればよいですか?そのメソッドで新しいタスクを作成した場合、そのタスクは低い優先度で実行されますか?基本的に、startProcessingItemsはリストで終わります。リストができたら、最高の優先度で実行を開始します。

4

3 に答える 3

5

これは良いアプローチではありません。まず、LinkedList<T>スレッドセーフではないため、2つのスレッドで書き込みと読み取りを行うと、競合状態が発生します。

より良いアプローチは、を使用することBlockingCollection<T>です。これにより、完全にスレッドセーフであるため、スレッドの安全性を気にすることなく、アイテム(プロデューサースレッド)を追加したり、アイテム(コンシューマースレッド)を読み取ったりできます。

blockingCollection.GetConsumingEnumerable()読み取りスレッドはaを呼び出しforeachて要素を取得するだけで、書き込みスレッドは要素を追加するだけです。読み取りスレッドは自動的にブロックされるため、優先順位を変更する必要はありません。

書き込みスレッドが「完了」したら、を呼び出すだけでCompleteAdding、読み取りスレッドが自動的に終了します。

于 2012-09-20T19:14:16.477 に答える
2

スレッド/プロセスの優先順位を変更するのではなく、固有の設計を変更することで、プログラムのパフォーマンスを向上させることができます。

あなたの問題の大部分はあなたがビジーウェイトをしているということです:

while(completed==false)
    Thread.Sleep(0);

その結果、生産的な作業を行わずに多くのCPUサイクルを消費することになります。そのため、優先度を下げると実行が速くなります。あなたが忙しく待っていなければ、それはもう問題にはなりません。

リードが示唆しているように、BlockingCollectionこの状況に合わせて作られています。を使用してアイテムを追加するプロデューサースレッドと、削除するアイテムがなくなった場合にメソッドが単純にブロックすることを知っているAddコンシューマースレッドを使用できます。Take

Task作成して使用したものを保存しTask.ResultたりTask.Wait、メインスレッドに他のタスクが終了するのを待たせたりすることもできます(CPUサイクルを無駄にすることなく)。(スレッドを直接使用している場合は、使用できますJoin。)

于 2012-09-20T19:17:32.997 に答える
2

リードとサービーが言ったことに加えて:

スレッドの優先度は、プロセスの優先度に関連しています。

Windowsスケジューラは、スレッドの時間をスケジュールするときに、他のすべてのスレッドを考慮に入れます。優先度の高いスレッドは、システムの他の部分を人為的に遅くする可能性のある他のスレッドから時間を奪います。システムにスレッドの優先順位を上げない理由がないわけではありません。優先順位は、他の何かがCPUをそれから奪った場合にのみ効果があります-これは理由で起こります。スレッドからCPUを奪うものが何もない場合、最高の優先度で魔法のように高速に実行されることはありません。

スレッドの優先度を最高に設定することは、ほとんどの場合、間違ったことです。

2つのスレッド間の同期のオーバーヘッドにより、パフォーマンスが向上すると思われる場合は、それが失われる可能性があります。

また、Thread.Sleep(0)は、同じ優先度のスレッドに時間を解放するだけで、実行の準備ができています。これにより、スレッドが不足する可能性があります。 http://msdn.microsoft.com/en-us/library/d00bd51t(v=vs.80).aspx

于 2012-09-20T19:20:29.163 に答える