InternetMaster
@InternetMaster
Интернет

Как убедиться что атомарные операции будут выполнены точно правильно?

Смотрите, несколько продвинутый вопрос. Есть две функции, которые запускаются в двух потоках.

#include <atomic>
#include <thread>
#include <assert.h>

std::atomic<bool> x;
std::atomic<int> z;

void write() {
	x.store(true, std::memory_order_release);
}

void get() {
	if (x.load(std::memory_order_acquire)) {
		++z;
	}
}

int main() {
	x = false;
	z = 0;
	std::thread a(write);
	std::thread b(get);
	a.join();
	b.join();
	assert(z.load() != 0);
}


При обычных обстоятельствах все вроде окей, но. Если случиться ситуация, что thread a запустится и сразу же прервется (т. е. менеджер потоков от OC не даст достаточно времени чтобы выполнилась эта операция записи, или ядро получит инструкцию прерывания и т.д.) А второй thread b запуститься как обычно. Получается, что x.load прочитает false (т.к. thread a не успел записать) и assert сработает. По-идеи никакие memory_order_seq_cst не спасут, ибо thread a не начнет данную инструкцию.

Какие есть пути отхода у вопроса? Понятно, что ситуация маловероятна, но нужно знать
  • Вопрос задан
  • 313 просмотров
Решения вопроса 2
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Когда вам важен порядок операций в разных потоках их надо синхронизировать по-другому. Атомарые операции тут точно не помогут. Нужны события. Один поток должен ожидать события, второй - сигнализировать его.

В стандартной библиотеке самое близкое к этом - std::condition_variable.

Платформо зависимое решение может быть эффективнее. Какие-нибудь WaitForSingleObject/CreateEvent в винде, например.
Ответ написан
Комментировать
@res2001
Developer, ex-admin
Ситуация вполне вероятна. На сколько я знаю, нет гарантии, что поток после создания сразу получит процессор для выполнения.
Делайте проверку в get в цикле, если x.load вернул false, то можно вызвать yield(), чтоб напрасно не жрать процессор в цикле.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
В данном исходнике нет проблемы атомиков. Но здесь есть проблема отсутсвия синхронизации потоков а и b.
Нужно наладить синхронизацию и дальше атомики станут приносить ощутимую пользу.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы