Выбор ответа Senior Многопоточность и модель памяти обновлено

Публикация данных через флаг

Вопрос

Поток A: data = 42; ready.store(true, std::memory_order_release);. Поток B: while (!ready.load(std::memory_order_acquire)) {} use(data);. Что гарантировано?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: B увидит data == 42: release-запись синхронизируется с acquire-чтением. Запись data предшествует release-записи в потоке A, acquire-чтение, увидевшее true, синхронизируется с ней, и всё, что было до release, happens-before всего, что после acquire.

Варианты ответа

  1. B увидит data == 42: release-запись синхронизируется с acquire-чтениемправильный ответ
  2. Ничего: data не атомарна, поэтому чтение в B это гонка данных
  3. B увидит 42, только если data тоже объявлена как std::atomic<int>
  4. Гарантия есть только на x86 с его сильной моделью памяти, на ARM нет

Разбор

Запись data предшествует release-записи в потоке A, acquire-чтение, увидевшее true, синхронизируется с ней, и всё, что было до release, happens-before всего, что после acquire. Гонки по data нет: обращения упорядочены.

  • data может быть обычной переменной, синхронизацию даёт атомарный флаг.
  • Гарантия дана стандартом для всех платформ. На x86 такие операции дешёвые, а на ARM компилятор вставит нужные барьеры.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.