1

オーバーフローの皆さん、こんにちは。

私は C# .Net 4 を使用しています。コードの特定の部分を優先して同時実行を利用したいのですが、他の部分も余裕がある場合 (空きコア) にのみ同じことができます。それ以外の場合は、順次実行に切り替える必要があります (単に一時的にブロックされるのではなく、呼び出し元スレッドで)。
どうやってやるの ?その特定の問題に関する最近の良い読書はありますか?
利用可能なコアがない場合、Parallel.Invoke(...) は呼び出し元のタスク/スレッドで順番に実行されますか?

よろしく

4

5 に答える 5

1

「フリースレッド」などというものはありません。未使用のコアのみがあります。Environment.ProcessorCount でそれらを単純にカウントし、それに基づいてスレッド戦略を立てることができます。通常、ThreadPool を利用しないのは間違いです。コア全体に tp スレッドを分散させるのに適しています。しかし、あなたが求めるものを簡単に与えることはできません。ThreadPool.GetAvailableThreads は絶えず変化する数値です。とにかくあるべきです。

于 2011-03-26T19:06:21.447 に答える
0

問題は優先順位付けです。重要なタスク(実行する必要がある)とレジャータスク(空きCPUがあり、重要なタスクがキューに入れられていない場合にのみ実行できる)の2種類のタスクがあると言っています。

簡単な解決策は、重要なタスクには非常に高い優先度を割り当て、レジャータスクには非常に低い優先度を割り当てることです。このようにして、システムのCPUリソースのほとんどが重要なタスクの実行に向けられることをほぼ保証します。ただし、すべての重要なタスクが実行された後、レジャータスクが常に実行されることを保証するものではありません。システムはまだ時々いくつかの余暇の仕事をスケジュールするかもしれません。

ただし、タスク並列ライブラリでは、優先度の異なるタスクをスケジュールすることはできません。このようなものを使用するか、常に重要なタスクを最初にデキューするBlockingCollectionのカスタム実装でTPLのスケジューラーをオーバーライドすることができます。

1つの解決策は、TPLを使用して重要なタスクをスケジュールすることですが、自分のバックグラウンドスレッド(最小のスレッド優先度に設定)でレジャータスクを手動でスケジュールします。このスレッドは、レジャータスクを順番に実行します。

于 2011-03-27T05:56:53.437 に答える
0

私のF#の経験では、コアアプリケーションコードの外部から同時実行の使用を制御/構成することが可能です。C#AsyncCTPが同様の機能を提供することを期待します。

于 2011-03-26T19:49:51.617 に答える
0

並列フレームワークが物理的な可用性に基づいてスレッドを分配しているという印象を受けました。http://msdn.microsoft.com/en-gb/concurrency/default.aspx

私は並列拡張機能 ( http://blogs.msdn.com/b/pfxteam/ ) について考えているかもしれませんし、それらは同じものかもしれませんし、くだらないことを話しているかもしれません :-)

于 2011-03-26T18:31:21.253 に答える
0

フリー スレッドは、.Net スレッド プールにのみ存在する概念です。あなたが意味したのは、おそらく空き CPU リソースです!?

new Thread() を使用して独自のスレッドを宣言している場合、それに拘束されることはありません。

ただし、それらの多くを生成すると、プロセスや OS の速度が低下する可能性があります。そのため、これを処理する独自のスレッド マネージャーを作成する必要があります。

CPU 使用率は次のように確認できます。

PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
double cpuUsage = Convert.ToDouble(cpuCounter.NextValue());

そして、コードで変数を使用して次のことを行います。

int threadId;
if (cpuUsage > threshold) {
    DoWork();
}
else {
    threadId = YourThreadManager.Queue(DoWork);
}
于 2011-03-26T20:02:32.323 に答える