Почему переменная volatile используется через out std :: atomic? - PullRequest
71 голосов
/ 19 марта 2010

Из того, что я прочитал из Херба Саттера и других , вы могли бы подумать, что volatile и параллельное программирование были полностью ортогональными понятиями, по крайней мере, до тех пор, пока C / C ++ обеспокоен.

Однако в реализации GCC все функции-члены std::atomic имеют квалификатор volatile. То же самое верно в реализации Энтони Уильямса из std::atomic.

Так в чем же дело, мои atomic<> переменные должны быть volatile или нет?

Ответы [ 3 ]

77 голосов
/ 19 марта 2010

Подводя итог тому, что правильно написали другие:

C / C ++ volatile для аппаратного доступа и прерываний. C ++ 11 atomic<> предназначен для связи между потоками (например, в коде без блокировки). Эти два понятия / использования являются ортогональными, но у них есть частично совпадающие требования, и именно поэтому люди часто путают их.

Причина, по которой atomic<> имеет функции с квалификацией volatile, является той же самой причиной, по которой у него функции с квалификацией const, поскольку в принципе возможно, что объект будет atomic<> и const и / или volatile.

Конечно, как указывалось в моей статье, еще одним источником путаницы является то, что C / C ++ volatile отличается от C # / Java volatile (последний в основном эквивалентен C ++ 11 atomic<>).

56 голосов
/ 19 марта 2010

Почему во всех std::atomic используется квалификатор volatile?

Так что летучие объекты также могут быть атомными. См здесь :

Соответствующая цитата

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

Должны ли мои atomic<> переменные быть volatile или нет?

Нет, атомные объекты не должны быть летучими.

15 голосов
/ 19 марта 2010

Как постоянный, летучий является переходным. Если вы объявите метод как volatile, то вы не сможете вызвать какой-либо энергонезависимый метод для него или любого из его атрибутов-членов. Имея std::atomic методы volatile, вы разрешаете вызовы от volatile методов-членов в классах, которые содержат std::atomic переменные.

У меня не очень хороший день ... такой запутанный ... может быть, поможет небольшой пример:

struct element {
   void op1() volatile;
   void op2();
};
struct container {
   void foo() volatile {
      e.op1();  // correct
      //e.op2();  // compile time error
   }
   element e;
};
...