С++ std:: atomic vs. Boost atom
В моем приложении у меня есть переменная int и bool, к которой обращаются (несколько записей/чтения) несколькими потоками. В настоящее время я использую два мьютекса, один для int и один для bool для защиты этих переменных.
Я слышал об использовании атомных переменных и операторов для написания незашифрованной многопоточной программы. Мои вопросы
- Что такое определение атомных переменных и операторов?
- Какое основное различие между std:: atomic и
импульс /atomic.hpp? Какой из них более стандартный или популярный?
- Являются ли эти библиотеки зависимыми от платформы? Я использую gnu gcc 4.6 на
Linux на данный момент, но в идеале он должен быть кросс-платформенным. Я слышал, что определение "атомный" на самом деле также зависит от аппаратного обеспечения. Может ли кто-нибудь объяснить это также?
- Какой лучший способ поделиться переменной bool между несколькими потоками? Я бы предпочел не использовать ключевое слово < volatile.
Являются ли эти коды безопасными для потока?
double double_m; // double_m is only accessed by current thread.
std::atomic<bool> atomic_bool_x;
atomic_bool_x = true && (double_m > 12.5);
int int_n; // int_n is only accessed by current thread.
std::atomic<int> atomic_int_x;
std::atomic<int> atomic_int_y;
atomic_int_y = atomic_int_x * int_n;
Ответы
Ответ 1
Я не эксперт или что-то еще, но вот что я знаю:
-
std::atomic
просто говорит, что одновременное определение вызовов load
и store
(и нескольких других операций) хорошо определено. Атомная операция неделима - ничего не может произойти "между".
- Я предполагаю, что
std::atomic
основан на boost::atomic
. Если вы можете, используйте std
, иначе используйте boost
.
- Они оба переносимы, при этом
std
будет полностью таким, однако ваш компилятор должен будет поддерживать С++ 11
- Вероятно
std::atomic_bool
. Вам не нужно использовать volatile.
Кроме того, я считаю, что load
/store
отличается от operator=
/operator T
только load
/store
атомарным.
Nevermind. Я проверил стандарт и выяснилось, что операторы определены в терминах load
/store
/etc, однако они могут возвращать разные вещи.
Дальнейшее чтение:
Ответ 2
Volatile ортогонален тому, что вы используете для реализации атомистики. В С++ он сообщает компилятору, что определенно небезопасно выполнять оптимизации с этой переменной. Трава Саттерс заявляет:
Чтобы безопасно писать код без блокировки, который обменивается данными между потоками без использования блокировок, предпочитайте использовать упорядоченные атомные переменные: Java/.NET volatile, С++ 0x atomic и C-compatible atomic_T.
Чтобы безопасно связываться со специальным оборудованием или другой памятью, имеющей необычную семантику, используйте неоптимизируемые переменные: ISO C/С++ volatile. Помните, что чтение и запись этих переменных не обязательно являются атомарными.
Наконец, чтобы выразить переменную, которая имеет необычную семантику и имеет какие-либо или все гарантии атомарности и/или порядка, необходимые для кодирования без блокировки, только стандартный стандарт ISO С++ 0x обеспечивает прямой способ его произнести: летучий атом.
(из http://drdobbs.com/article/print?articleId=212701484&siteSectionName=parallel)
Ответ 3
Ответ 4
Я считаю, что std::atomic
(С++ 11) и boost.atomic
эквивалентны. Если std::atomic
еще не поддерживается вашим компилятором, используйте boost::atomic
.