別の開発者によって書かれたいくつかのコードを読んだ後に疑問が生じたので、調査を行ったところ、Andrei Alexandrescu の記事を見つけました。彼の記事では、忙しい待機のために揮発性ブール変数を使用することが可能であると述べています (待機/ウェイクアップの最初の例を参照してください)。
class Gadget
{
public:
void Wait()
{
while (!flag_)
{
Sleep(1000); // sleeps for 1000 milliseconds
}
}
void Wakeup()
{
flag_ = true;
}
...
private:
bool flag_;
};
私はそれがどのように機能するのか本当にわかりません。
- volatile は、操作がアトミックであることを保証しません。実際には、ブール変数への読み取り/書き込みはアトミックですが、理論はそれを保証しません。私の観点からすると、上記のコードは、std::atomic::load/store 関数を使用して、それに応じてメモリの順序付け制約を取得/解放することにより、C++11 で安全に書き直すことができます。
- 説明した例ではこの問題はありませんが、複数の書き込みがある場合、メモリの順序付けに問題が発生する可能性があります。揮発性はフェンスではなく、メモリの順序付けを強制するものではなく、コンパイラの最適化を妨げるだけです。
では、なぜ多くの人が忙しい待機に volatile bool を使用し、それは本当に移植性があるのでしょうか?