Подтвердить что ты не робот

Является ли volatile int в C таким же хорошим, как std:: atomic <int> для С++ 0x?

Мне нужно иметь атомные переменные в моей программе. Раньше я использовал std::atomic<int>, но платформа, на которой я сейчас работаю, не имеет компилятора g++, который поддерживает С++ 0x. Я использовал volatile int и, похоже, работает, так как я еще не испытал состояние гонки в многоядерной системе, на которой я тестирую ее.

Мой вопрос: если volatile int атомный, как std::atomic<int>? Кроме того, создает ли барьеры памяти (что также требуется)?

4b9b3361

Ответ 2

Нет. volatile не имеет никакого отношения к многопоточности. Он не защищает барьер памяти (хотя некоторые компиляторы, возможно, захотят добавить это в любом случае), и он не дает никаких гарантий относительно переупорядочения записи/записи в отношении энергонезависимых объектов.

volatile был добавлен для поддержки записи в регистры ввода-вывода с отображением памяти, и в таких случаях, когда важно, чтобы ваша запись не оптимизировалась, но нет точных гарантий заказа. требуются нелетучие чтения/морщины.

Вы также можете прочитать this

Ответ 3

Летучие переменные НЕ подразумевают барьеры памяти и не имеют операций exchange или compare_exchange_* std::atomic. Они не позволяют компилятору поднимать нагрузку на несколько нагрузок на уровне машинного кода (и наоборот, и аналогично для магазинов), но что он.

Вам могут быть интересны следующие статьи:

Если у вас нет std::atomic, вы можете использовать boost:: atomic или использовать низкоуровневый барьер и атомный -операционные примитивы, предлагаемые любым компилятором, который вы используете.

Ответ 4

До С++ 0x язык не был осведомлен о потоке, поэтому он не предотвращал множественный доступ. Объявление им изменчивости поможет некоторым, но оно не будет препятствовать гонкам.

Подробнее см. http://en.wikipedia.org/wiki/Volatile_variable.

Чтобы действительно сделать операции атомарными, вам нужно использовать любой механизм блокировки вашей библиотеки потоков (win32 threads, pthreads и т.д.).

Ответ 5

Здесь есть хорошее описание различий здесь, от Herb Sutter. Вкратце (вырезать и вставить):

Чтобы безопасно писать код без блокировки, который осуществляет связь между потоками без используя блокировки, предпочитают использовать упорядоченные атомные переменные: переменная Java/.NET, С++ 0x атомный и C-совместимый atomic_t.

Безопасное общение со специальными аппаратной или другой памяти, необычная семантика, используйте unoptimizable переменные: изменчивость ISO C/С++. Помните, что чтение и запись эти переменные не обязательно атома, однако.

Ответ 6

volatile в основном сообщает компилятору, что он не может делать предположения о том, что находится в определенном месте памяти. Например,

bool test = true;
while(!test)
{
    /* do something (e.g. wait) */
}

компилятор может оптимизировать весь while, поскольку он предполагает, что test всегда истинно. Если, однако, test в какой-то момент будет обновляться из другого места (например, для какого-то оборудования или другого потока), мы не хотим, чтобы компилятор предположил, что он знает, что находится в test. Мы можем сказать компилятору, что с помощью volatile.

Как утверждают другие ответы, он не дает никаких гарантий относительно того, какой порядок вещей попадает в ячейку памяти.

P.s. Я бесстыдно украл этот пример откуда-то, но не мог вспомнить, где я его видел.