Что не так с последовательной последовательностью здесь?

Я играю с алгоритмами без блокировок в C и C ++ и недавно наткнулся на поведение, которое я не совсем понимаю. Если у вас есть следующий код, его запуск даст вам что-то вроде

читатель начал
писатель начал
иттерс = 79895047, меньше = 401131, экв = 48996928, больше = 30496988

не являются std::atomics как ожидается, будет последовательно последовательным? Если так, то почему читатель иногда видит b обновляется раньше a? Я также безуспешно пытался делать различные трюки с заборами памяти. Полный скомпилированный код можно увидеть на https://github.com/akamaus/fence_test

Что не так с примером?

std::atomic<uint> a(0);
std::atomic<uint> b(0);

volatile bool stop = false;

void *reader(void *p) {
uint64_t iter_counter = 0;
uint cnt_less = 0,
cnt_eq = 0,
cnt_more = 0;

uint aa, bb;printf("reader started\n");

while(!stop) {
iter_counter++;
aa = a.load(std::memory_order_seq_cst);
bb = b.load(std::memory_order_seq_cst);
if (aa < bb) {
cnt_less++;
} else if (aa > bb) {
cnt_more++;
} else {
cnt_eq++;
}
}
printf("iters=%lu, less=%u, eq=%u, more=%u\n", iter_counter, cnt_less, cnt_eq, cnt_more);

return NULL;
}

void *writer(void *p) {
printf("writer started\n");
uint counter = 0;
while(!stop) {
a.store(counter, std::memory_order_seq_cst);
b.store(counter, std::memory_order_seq_cst);
counter++;
}
}

1

Решение

Последовательное последовательное упорядочение памяти подразумевает, что порядок модификации (атомных объектов, манипулируемых последовательностью), наблюдаемый всеми потоками, является согласованным. Программа ведет себя так, как будто все эти операции выполняются с чередованием в одном общем порядке. Рассмотрим следующие случаи:


Писатель читатель
== 0
а = 1
б = 1
б == 1

Результат: aa < bb,


Писатель читатель
а = 1
== 1
б == 0
б = 1

Результат: aa > bb


С замком, например mutex, вы можете убедиться, что операции не чередуются.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]