0

マルチスレッドアプリでは、

while (result->Status == Result::InProgress) Sleep(50);
//process results

より良い

while (result->Status == Result::InProgress);
//process results

? それにより、最初の方法は、常に回転するのではなく、結果を待っている間、他のスレッドに礼儀正しくなるでしょうか? 私が待っている操作は、通常、約 1 ~ 2 秒かかり、別のスレッド上にあります。

4

4 に答える 4

2

このような場合は、ポーリングの代わりにセマフォを使用することをお勧めします。アクティブな待機を好む場合は、ループ状態を常に評価するよりもスリープの方がはるかに優れたソリューションです。

于 2012-06-27T14:34:29.430 に答える
1

より良いですが、それほどではありません。

result->Statusでない限りvolatile、コンパイラは削減できます。

while(result->Status == Result::InProgress);

if(result->Status == Result::InProgress) for(;;) ;

ループ内で条件が変化しないためです。

外部 (したがって暗黙的にvolatile) 関数を呼び出すとSleep、これが変更されます。これresultは、コンパイラがSleepデータを変更しないことを認識していない限り、構造が変更される可能性があるためです。したがって、コンパイラによっては、2 番目の実装の方が無限ループに陥る可能性がはるかに低くなります。

result->Statusへのアクセスがアトミックになるという保証もありません。特定のメモリ レイアウトとプロセッサ アーキテクチャの場合、この変数の読み取りと書き込みは複数の手順で構成される場合があります。つまり、スケジューラが途中で介入することを決定する場合があります。

この時点で通信しているのは単純なはい/いいえだけであり、受信スレッドも否定応答を待機する必要があるため、OS が提供する適切なスレッド同期プリミティブを使用してこの効果を実現するのが最善の方法です。これには、条件が変わるとすぐにスレッドが起動され、OS がスレッドが何を待っているかを認識しているため、その間 CPU を使用しないという利点があります。

Windows では、CreateEventand co を使用します。イベント オブジェクトを使用して通信する。Unix では、pthread_cond_tオブジェクトを使用します。

于 2012-06-27T14:49:16.687 に答える
1

これは、OS のスケジューリング ポリシーにも依存します。たとえば、Linux にはデフォルトで CFS スケジューラがあり、すべてのタスクにプロセッサを公平に分配します。しかし、FIFO ポリシーを使用してこのスレッドをリアルタイム スレッドとして作成すると、スリープのないコードはプロセッサを放棄することはなく、より優先度の高いスレッドが来ない限り、ループから抜け出すまで同じ優先度またはそれ以下の優先度は決してスケジュールされません。SCHED_RR を適用すると、同じ優先度以上のプロセスがスケジュールされますが、低くはなりません。

于 2012-06-27T14:51:15.537 に答える
1

はい、スリープとバリアントはプロセッサを放棄します。他のスレッドが引き継ぐことができます。しかし、他のスレッドを待つより良い方法があります。

空のループを使用しないでください。

于 2012-06-27T14:33:26.850 に答える