C++ отношения «происходит до» и «memory_order_consume»C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 C++ отношения «происходит до» и «memory_order_consume»

Сообщение Anonymous »

Рассмотрим следующий пример использования std::memory_order_consume для синхронизации данных:

Код: Выделить всё

struct X
{
int i;
std::string s;
};

std::atomic p;
std::atomic a;

void create_x()
{
X* x=new X;
x->i=42;
x->s="hello";
a.store(99,std::memory_order_relaxed);                     //1
p.store(x,std::memory_order_release);                      //2
}

void use_x()
{
X* x;
while(!(x=p.load(std::memory_order_consume)))              //3
std::this_thread::sleep(std::chrono::microseconds(1));

assert(x->i==42);                                          //4
assert(x->s=="hello");                                    // 5

assert(a.load(std::memory_order_relaxed)==99);            // 6
}

int main()
{
std::thread t1(create_x);
std::thread t2(use_x);
t1.join();
t2.join();
}
Энтони Уильямс в своей книге «Конкуренция в действии» дает следующее объяснение:

Несмотря на то, что сохранение в 1 упорядочивается перед сохранением в p 2, и
сохранение в p помечается тегом Memory_order_release, загрузка p 3
помечается тегом Memory_order_consume. Это означает, что сохранение в p происходит только
до тех выражений, которые зависят от значения
, загруженного из p. Это означает, что утверждения элементов данных структуры
X (4 и 5) гарантированно не сработают, поскольку нагрузка
p несет зависимость от этих выражений через переменную x. С другой стороны, утверждение значения 6 может сработать, а может и не сработать;
эта операция не зависит от значения, загруженного из p, и поэтому
нет никакой гарантии относительно прочитанного значения. Это особенно
очевидно, потому что оно отмечено тегом Memory_order_relaxed.

Это объяснение имеет смысл, но когда я пытаюсь подумать об этом с точки зрения отношений «происходит до», определенных cppreference, я не могу прийти к такому же выводу:
  • Между хранилищами 1 и «происходит до» существуют отношения «последовательность до» и «происходит до» 2
  • Между 2 и 3 существует связь «упорядоченный порядок до» и «происходит перед потоком» между 2 и 3.
  • Поскольку связь «происходит перед потоком» сочетается с связью «упорядоченный перед», сохранение 1 происходит перед загрузкой 3, и, следовательно, 1 происходит до загрузки 3.
  • Нагрузка 3 последовательность-до загрузки 6 по порядку программы, следовательно 3 происходит-до 6
  • Как мы пришли к выводу, 1 происходит-до 3 и 3 происходит-до 6, то по транзитивности 1 происходит-до 6
Последнее утверждение, кажется, противоречит тому, что написано в книге. В моей логической цепочке ошибка или то, что происходит сохранение 1-до загрузки 6, не обязательно означает, что эффекты 1 видны 6?

Подробнее здесь: https://stackoverflow.com/questions/792 ... er-consume
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»