Я разрабатываю многопоточный алгоритм, в котором требуется прочитать последнее значение общей переменной. Записи в переменную являются атомарными (с использованием метода сравнения и замены). Однако чтения не атомарны.
Рассмотрим следующий пример:
//Global variable
int a = 10;
// Thread T1
void func_1() {
__sync_bool_compare_and_swap(&a, 10, 100);
}
// Thread T2
void func_2() {
int c = a;
/* Some Operations */
int b = a;
/* Some Operations */
}
Если код int b = a
выполняется (потоком T2) после __sync_bool_compare_and_swap
в func_1 (потоком T1), то, как я понимаю, по-прежнему не гарантируется чтение последнего значения «переменной a», поскольку компилятор может кэшировать «a» и используйте старое значение «а».
Теперь, чтобы избежать этой проблемы, я объявил переменную volatile, как показано ниже:
volatile int a = 10;
// Thread T1
void func_1() {
__sync_bool_compare_and_swap(&a, 10, 100);
}
// Thread T2
void func_2() {
volatile int c = a;
/* Some Operations */
volatile int b = a;
/* Some Operations */
}
Для того же сценария выполнения int b = a
потоком T2 после завершения __sync_bool_compare_and_swap
потоком T1, гарантировано ли чтение последнего значения «a»?
Как модель согласованности кэша и согласованности памяти повлияет на энергозависимое чтение после атомарной записи?
std::atomic<int>
? - person Jarod42   schedule 30.12.2015volatile int b = a;
не безопаснее, чемint b = a;
. Другой поток все равно не будет изменятьb
(копиюa
). Проблема может появиться в назначении, иvolatile int a
не решает ее (но проблема может появляться реже). - person Jarod42   schedule 30.12.2015