Мне нужно атомарно назначить a = b
если условие c
держит, и не присваивает, если условие не выполняется. Есть ли способ сделать это в C / C ++?
Пояснение: я имел в виду атомарно «проверить и назначить», а не «атомно назначить».
Там нет ни одной операции, которая выполняет то, что вам нужно в целом. Общий случай, когда является покрывается ли тот случай, когда ваше состояние c
тесты если a
уже установлено какое-то конкретное значение. В этом случае вам нужна операция сравнения и обмена, например:
std::atomic<int> value;
...
int expected = 9;
bool result = std::atomic_compare_exchange_strong(&value, &expected, 10);
Вот value
устанавливается на 10, только если условие value == 9
верно, вся операция является атомной.
Если ваше состояние не принимает эту форму, вам придется использовать мьютексы (или какой-либо другой механизм множественных операций) для достижения атомарности.
Если c
какое-то свойство a
Сам, тогда сравнительно-обменные атомные операции могут решить ваши проблемы. Вы указали в комментариях, что это не так.
В противном случае, оберните все доступ c
(все, что читает его состояние или изменяет его состояние) и a
в замках общего std::mutex
,
Тестовое задание c
и назначить a
в замке этого std::mutex
,
В противном случае напишите однопоточную программу.
В противном случае используйте API уровня ОС, чтобы приостановить все потоки в вашем процессе, кроме себя, а затем протестируйте c
и, возможно, назначить a
, Обратите внимание, что это можно увидеть c
или же a
в состоянии, где оно написано наполовину (т. е. в некогерентном состоянии), и с планом приостановки потока действительно не существует практического способа избежать его, если оба c
а также a
сами по себе не имеют блокировки.
Обратите внимание, что этот план чрезвычайно опасен и хрупок.
Если это не так, опишите вашу проблему менее абстрактно и задайте другой вопрос. Шансы на менее абстрактную версию вашей проблемы будут разумными.