Нужен ли мне барьер памяти для доступа к памяти, измененной завершившимся потоком?

[Здесь и далее термины C ++]

У меня есть поток A и поток B, которые имеют общий доступ к целочисленному значению P. Поток A инициализирует это значение и обновляет его во время работы. Затем поток A завершается. Поток B ожидает завершения потока A (стандартный вызов API ОС, какая бы ОС ни использовалась) и хочет прочитать P.

Требуется ли потоку B барьер памяти для чтения связного, последнего установленного потоком A, значения из P? Есть ли вероятность, что когда API ОС сообщает «поток A завершен», изменения в памяти, которые он изменил, еще не будут видны другим потокам?

Обратите внимание, что здесь только один поток записывает здесь значение, что может отличить этот вопрос от "Есть ли неявный барьер памяти с отношениями synchronized-with в thread :: join? ", - спрашивали раньше. Мое чутье подсказывает мне, что ответ должен быть таким же, но ...


person NSH    schedule 29.03.2017    source источник
comment
Похоже, это работа для `std :: future.   -  person Pete Becker    schedule 29.03.2017
comment
Прочитав это, я бы сказал, что да -. join () синхронизируется, и вам не нужен барьер памяти. Но этот текст написан не для интерпретации обычными смертными, поэтому я оставлю ответ кому-то другому. Возможно, дубликат stackoverflow.com/questions/12444891/   -  person nos    schedule 29.03.2017


Ответы (1)


join синхронизируется с потоком, вызывающим join. То есть все записи, которые делает A, станут видимыми для B, когда B вызовет A.join().

Вы можете думать об этом как о A выполнении std::atomic_thread_fence(memory_order_release) по завершении и B выполнении std::atomic_thread_fence(std::memory_order_acquire при присоединении A.

Нужен ли поток B барьер памяти

Да, но они неявны в join, и вам не нужно их писать.

Есть ли вероятность, что когда API ОС сообщает «поток A завершен», изменения в памяти, которые он изменил, еще не будут видны другим потокам?

Потокам, отличным от вызывающего join, потребуется дополнительная синхронизация, например std::condition_variable или std::atomic_thread_fence(std::memory_order_acquire);

person Pubby    schedule 29.03.2017