Почему c ++ 11 memory_order_relaxed все еще приводит к последовательному ожиданию? - PullRequest
0 голосов
/ 27 января 2020

Я ожидаю, что загрузка атома c не должна будет ждать присвоения значения, но у меня есть код ниже:

#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
using namespace std;
atomic<bool> y;
void write()
{
    this_thread::sleep_for(chrono::seconds(2));
    cout<<"end sleep\n";
    y.store(true,memory_order_relaxed);
}
void read()
{
    while(!y.load(memory_order_relaxed));
    cout<<"end load\n";
}
int main() {
    y = false;
    thread a(write);
    thread b(read);
    a.join();
    b.join();
    cout<<y.load()<<endl;
}

Основное запустится, подождет 2 секунды, а затем напечатает:

end sleep
end load
1

Я запускал его много раз, и всегда один и тот же результат.

Так что мне кажется, что функция "read ()" atomic_load "будет ждать" write () "функция" сохранить "до конца sh. Это проблема моей программы или дизайн порядка памяти в c ++ 11?

Я на Ubuntu18.04 и G ++. Спасибо.

1 Ответ

2 голосов
/ 27 января 2020

Ваша функция read имеет while l oop, которая повторяется до тех пор, пока значение, считываемое y.load(), не станет ненулевым. Следовательно, это будет l oop до тех пор, пока хранилище от 1 до y не станет видимым для этого потока.

Вызовы join до печати в main затем гарантируют, что оба потока завершены, и, таким образом, хранилище от 1 до y было завершено и до печати. ​​

...