Это приобретенный забор наблюдается? - PullRequest
0 голосов
/ 27 июня 2019

Этот вопрос касается автономных заборов в C ++

В попытке инкапсулировать использование заборов выпуска и выпуска я написал следующий код:

#include <thread>
#include <atomic>
#include <cassert>

class sync {
    std::atomic<bool> flag{false};

public:
    void release()
    {
        std::atomic_thread_fence(std::memory_order_release);
        flag.store(true, std::memory_order_relaxed);
    }

    bool acquire()
    {
        return flag.load(std::memory_order_relaxed);
        std::atomic_thread_fence(std::memory_order_acquire); // Is this acquire fence observed by the application ?
    }
};

int main()
{
    sync s;
    int data = 0;

    std::thread t1{[&] { data = 12; s.release(); }};
    std::thread t2{[&] { if (s.acquire()) assert(data==12); }};

    t1.join(); t2.join();
}

Я считаю, чтозаборы расположены правильно («отпустить» перед магазином и «приобрести» после загрузки).

Я не уверен, действительно ли работает загрузка / получение.
Поскольку предел получения составляет после оператора загрузки / возврата, мне интересно, принимается ли он во внимание вообще?,

Правильно ли использовать этот забор?

1 Ответ

2 голосов
/ 01 июля 2019

Нельзя ставить забор после return. Ваше размещение забора забора является недоступным кодом. std::atomic_thread_fence - это функция. Не относитесь к этому, как к языковой функции Если вы не вызываете функцию, вы не получите эффект.

Я скомпилировал ваш пример в MSVC 19.16 (VS 2017 15.9.13) с уровнем предупреждения компилятора 4 (флаг /w4). Я получил предупреждение о "недоступном коде".

Предупреждение GCC о недоступном коде было удалено в версии 4.5 https://stackoverflow.com/a/21240321/9107647

Fix (адаптировано с https://preshing.com/20130922/acquire-and-release-fences/):

bool acquire()
{
    if (flag.load(std::memory_order_relaxed))
    {
        std::atomic_thread_fence(std::memory_order_acquire);
        return true;
    }
    return false;
}
...