При использовании порядка памяти seq_cst следующий код никогда не должен иметь v1 == 0 и v2 == 2 . Но он по-прежнему просто печатает: «Переупорядочение произошло на моем чипе Apple M1». Я действительно не знаю почему.
#include
#include
#include
#include
std::atomic v1, v2;
sem_t start_1, start_2, complete;
int main() {
sem_init(&start_1, 0, 0);
sem_init(&start_2, 0, 0);
sem_init(&complete, 0, 0);
std::thread t1([&] {
while (true) {
sem_wait(&start_1);
v1.store(1, std::memory_order_seq_cst);
asm volatile("":: : "memory");
v2.store(2, std::memory_order_seq_cst);
sem_post(&complete);
}
});
std::thread t2([&] {
while (true) {
sem_wait(&start_2);
int val1 = v1.load(std::memory_order_seq_cst);
asm volatile("":: : "memory");
int val2 = v2.load(std::memory_order_seq_cst);
if (val1 == 0 && val2 == 2) {
puts("Reorder happened");
}
sem_post(&complete);
}
});
for (int i = 0; i < 1000000; i++) {
v1 = v2 = 0;
sem_post(&start_1);
sem_post(&start_2);
sem_wait(&complete);
sem_wait(&complete);
}
t1.detach();
t2.detach();
return 0;
}
Обновление:
Большое спасибо ответ Питера Кордеса: я пропустил одну из возможностей чередования. Но меня все еще смущает следующий код. Тем не менее, я думаю, что с порядком seq_cst r1 == 0 и r2 == 0 не должно произойти. Он хорошо работает на моем компьютере Intel x86, но не на моем процессоре Apple M1.
#include
#include
#include
#include
std::atomic v1, v2;
std::atomic r1, r2;
sem_t start_1, start_2, complete;
int main() {
sem_init(&start_1, 0, 0);
sem_init(&start_2, 0, 0);
sem_init(&complete, 0, 0);
std::thread t1([&] {
while (true) {
sem_wait(&start_1);
v1.store(1, std::memory_order_seq_cst);
asm volatile("":: :"memory");
int val = v2.load(std::memory_order_seq_cst);
asm volatile("":: :"memory");
r1.store(val, std::memory_order_seq_cst);
sem_post(&complete);
}
});
std::thread t2([&] {
while (true) {
sem_wait(&start_2);
v2.store(1, std::memory_order_seq_cst);
asm volatile("":: :"memory");
int val = v1.load(std::memory_order_seq_cst);
asm volatile("":: :"memory");
r2.store(val, std::memory_order_seq_cst);
sem_post(&complete);
}
});
for (int i = 0; i < 1000000; i++) {
v1 = v2 = 0;
sem_post(&start_1);
sem_post(&start_2);
sem_wait(&complete);
sem_wait(&complete);
if (r1 == 0 && r2 == 0) {
printf("reorder detected @ %d\n", i);
}
}
t1.detach();
t2.detach();
return 0;
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... th-seq-cst