より良いですが、それほどではありません。
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 では、CreateEvent
and co を使用します。イベント オブジェクトを使用して通信する。Unix では、pthread_cond_t
オブジェクトを使用します。