Может ли один поток «безопасно» читать переменную, записанную другим потоком, без охраны?

Позвольте мне определиться с уверенностью: не возвращает тарабарщины. Давайте предположим, что у меня есть переменная любого типа; для этого примера я использую int и класс

class Example
  {
  int a;
  public: 
    void set_int(int b) { a = b; }
    void do_stuff() { std::cout << a << std::endl; }
  }

Если один поток непредсказуемо вызывает set_int, а другой поток периодически вызывает do_stuff (), в случае коллизии я просто собираюсь вывести на консоль старое значение (которое в моем случае все еще хорошо), или я собираюсь увидеть совершенно непредсказуемые значения на?

Обратите внимание, что любое изменение, внесенное в класс, о котором я говорю, является только переназначением значения, нет добавления элементов в контейнеры или тому подобное, никаких индексов или итераторов; просто ценности.

Всего 1 ответ


Может ли один поток «безопасно» читать переменную, записанную другим потоком, без охраны?

Да, с предварительным условием, что обе операции упорядочены по отношению друг к другу. Как правило, требование, чтобы это условие было выполнено, состояло в том, чтобы обе операции были атомарными, и это выполняется для атомарных типов. Операции чтения и записи для неатомарных типов неупорядочены по отношению к операциям в других потоках, если только этот порядок не установлен посредством взаимного исключения (см. std::mutex ). Неупорядоченные операции в потоках, в которых по крайней мере один является записью, приводят к неопределенному поведению

int который вы использовали в этом примере, не гарантированно является атомарным типом в C ++. Экземпляры шаблона std::atomic гарантированно будут атомарными - ну, по крайней мере, стандартными; если вы определяете пользовательские специализации, то обязательно используйте взаимное исключение, чтобы они оставались атомарными, чтобы избежать путаницы.


Есть идеи?

10000