Использование relaxed atomic boolean для синхронизации двух потоков

Некоторые коллеги и я обсуждают расслабленный атомарный логический тип, который используется для синхронизации двух потоков. Мы провели некоторые онлайн-исследования и нашли другие образцы и фрагменты, касающиеся расслабленной атомики, но мы не можем сделать какие-либо выводы из тех, которые применимы к нашему примеру.

Следующее атомное логическое значение распределяется между двумя потоками.

std::atomic_bool stopping{false};

Первый поток входит в цикл и завершается только после установки атомного логического значения. Обратите внимание, что нагрузка на каждой итерации цикла помечается как расслабленная.

// Thread 1
while (!stopping.load(std::memory_order_relaxed))
{
    // ...
}

В какой-то момент после того, как первый поток вошел в цикл (гарантированный каким-то другим механизмом синхронизации), второй поток выполняет следующий оператор. Опять же, обратите внимание, что магазин здесь отмечен непринужденно.

// Thread 2
stopping.store(true, std::memory_order_relaxed);

Вопрос: с чисто теоретической точки зрения, является ли первый поток гарантированно выходящим из цикла; и почему?


Поскольку мы считаем, что понимаем расслабленную атомность, мы думаем, что операция загрузки не гарантирует изменения операции записи. Но другие онлайн-примеры, касающиеся потоковобезопасных счетчиков, заставили нас поверить, что нагрузка все же подберет модификацию...

1 ответ

Поток 1 выйдет из цикла через определенный промежуток времени, это требование языка [basic.exec] / 18:

Реализация должна гарантировать, что последнее значение (в порядке модификации), назначенное атомарной операцией или операцией синхронизации, станет видимым для всех других потоков за конечный период времени.

Примечание: если нить 2, последний магазин false в атомном потоке 1 может никогда не увидеть состояние true атомного.

NB2: Я только что назвал ваш вопрос, используя расслабленную атомарность для синхронизации потока: это невозможно.

Другие вопросы по тегам