упорядочение памяти с помощью спиновой блокировки atomic_flag

Я пытаюсь познакомиться с новыми концепциями упорядочения памяти в c ++ 11 и считал, что на самом деле довольно хорошо их понимаю, пока не наткнулся на эту реализацию спин-блокировки:

#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 );
            }
        };
    }
}

Это, например, эквивалентно упоминается вhttp://en.cppreference.com/w/cpp/atomic/atomic_flag
а также в книге «Параллелизм в действии». Я также нашел это где-то здесь, в SO.

Но я просто не понимаю, почему это будет работать!
Представьте себе, что поток 1 вызывает lock (), а test_and_set () возвращает 0 как старое значение -> поток 1 получил блокировку.
Но затем поток 2 приходит и пытается то же самое. Теперь, поскольку не произошло никакой "синхронизации магазина" (release, seq_cst_acq_rel), хранилище потока 1 в spin_lock должно быть типа relaxed.
Но из этого следует, что он не может быть синхронизирован с чтением потока 2 spin_lock. Это должно позволить потоку 2 прочитать значение 0 из spin_lock и, таким образом, также получить блокировку.
Где моя ошибка?

Ответы на вопрос(3)

Ваш ответ на вопрос