1

別の開発者によって書かれたいくつかのコードを読んだ後に疑問が生じたので、調査を行ったところ、Andrei Alexandrescu の記事を見つけました。彼の記事では、忙しい待機のために揮発性ブール変数を使用することが可能であると述べています (待機/ウェイクアップの最初の例を参照してください)。

class Gadget
{
public:
    void Wait()
    {
        while (!flag_)
        {
            Sleep(1000); // sleeps for 1000 milliseconds
        }
    }
    void Wakeup()
    {
        flag_ = true;
    }
    ...
private:
    bool flag_;
};

私はそれがどのように機能するのか本当にわかりません。

  1. volatile は、操作がアトミックであることを保証しません。実際には、ブール変数への読み取り/書き込みはアトミックですが、理論はそれを保証しません。私の観点からすると、上記のコードは、std::atomic::load/store 関数を使用して、それに応じてメモリの順序付け制約を取得/解放することにより、C++11 で安全に書き直すことができます。
  2. 説明した例ではこの問題はありませんが、複数の書き込みがある場合、メモリの順序付けに問題が発生する可能性があります。揮発性はフェンスではなく、メモリの順序付けを強制するものではなく、コンパイラの最適化を妨げるだけです。

では、なぜ多くの人が忙しい待機に volatile bool を使用し、それは本当に移植性があるのでしょうか?

4

2 に答える 2

2

この記事では、これだけで十分だとは言っていませんvolatile(実際、そうではありません)。

これを行い、単純なジェネリック コンポーネントを使用すると、LockingPtrスレッド セーフなコードを記述でき、競合状態について心配する必要がほとんどなくなります。

于 2013-11-12T15:51:15.380 に答える
0

I don't really get how does it work.

It relies on two assumptions:

  • reads and writes to boolean variables are atomic;
  • all threads have a uniform view of memory, so that modifications made on one thread will be visible to others within a short amount of time without an explicit memory barrier.

The first is likely to hold on any sane architecture. The second holds on any single-core architecture, and on the multi-core architectures in widespread use today, but there's no guarantee that it will continue to hold in the future.

the code above could be safely rewritten with C++11 by using std::atomic

Today, it can and should be. In 2001, when the article was written, not so much.

if we have more then one write we may have problems with memory ordering

Indeed. If this mechanism is used for synchronisation with other data, then we're relying on a third assumption: that modification order is preserved. Again, most popular processors give that behaviour, but there's no guarantee that this will continue.

why so many people use volatile bool for busy wait

Because they can't or won't change habits they formed before C++ acquired a multi-threaded memory model.

and is it really portable?

No. The C++11 memory model doesn't guarantee any of these assumptions, and there's a good chance that they will become impractical for future hardware to support, as the typical number of cores grows. volatile was never a solution for thread synchronisation, and that goes doubly now that the language does provide the correct solutions.

于 2013-11-12T16:35:20.740 に答える