zamawianie pamięci za pomocą blokady spinowej atomic_flag

Próbuję zapoznać się z nowymi koncepcjami zamawiania pamięci c ++ 11 i wierzyłem, że naprawdę dobrze się z nimi zapoznałem, aż natknąłem się na implementację blokady spinowej:

#include <atomic>

namespace JayZ
{
    namespace Tools
    {
        class SpinLock
        {
        private:
            std::atomic_flag spin_lock;
        public:
            inline SpinLock( void ) : atomic_flag( ATOMIC_FLAG_INIT ) {}

            inline void lock( void )
            {
                while( spin_lock.test_and_set( std::memory_order_acquire ) )
                    ;
            }

            inline void unlock( void )
            {
                lock.clear( std::memory_order_release );
            }
        };
    }
}

To jest np. ekwiwalentnie wspomniany whttp://en.cppreference.com/w/cpp/atomic/atomic_flag
a także w książce „Concurrency in Action”. Znalazłem to także gdzieś tutaj w SO.

Ale po prostu nie rozumiem, dlaczego to zadziała!
Wyobraź sobie, że wątek 1 wywołuje lock (), a test_and_set () zwraca 0, ponieważ stara wartość -> wątek 1 uzyskał blokadę.
Ale potem pojawia się wątek 2 i próbuje tego samego. Teraz, gdy nie wystąpił żaden „synchronizacja sklepu” (wydanie, seq_cst_acq_rel), wątek 1 sklepu do spin_lock powinien być typu zrelaksowanego.
Ale z tego wynika, że ​​nie można zsynchronizować z odczytem spin_lock wątku 2. Powinno to umożliwić wątkowi 2 odczytanie wartości 0 z spin_lock, a tym samym uzyskanie blokady.
Gdzie jest mój błąd?

questionAnswers(3)

yourAnswerToTheQuestion