C Language
атомная энергетика
Поиск…
Синтаксис
-
#ifdef __STDC_NO_ATOMICS__ -
# error this implementation needs atomics -
#endif -
#include <stdatomic.h> - unsigned _Atomic counter = ATOMIC_VAR_INIT (0);
замечания
Atomics как часть языка C является дополнительной функцией, доступной с C11.
Их цель - обеспечить беспроблемный доступ к переменным, которые разделяются между различными потоками. Без атомной квалификации состояние общей переменной не будет определено, если два потока обращаются к нему одновременно. Например, операцию приращения ( ++ ) можно разделить на несколько команд ассемблера, чтение, само добавление и инструкцию хранилища. Если другой поток будет выполнять одну и ту же операцию, их две последовательности команд могут быть переплетены и привести к несогласованному результату.
Типы. Все типы объектов, за исключением типов массивов, могут быть квалифицированы с помощью
_Atomic.Операторы: все операции чтения-изменения-записи (например,
++или*=) на них гарантированно являются атомарными.Операции: Существуют и другие операции, которые задаются как общие функции типа, например,
atomic_compare_exchange.Темы: Доступ к ним гарантированно не приведет к сбору данных, когда к ним обращаются разные потоки.
Обработчики сигналов: Атомные типы называются блокируемыми, если все операции с ними не имеют состояния. В этом случае они также могут использоваться для обработки изменений состояния между нормальным потоком управления и обработчиком сигналов.
Существует только один тип данных, который гарантированно блокируется:
atomic_flag. Это минимальный тип операций, которые предназначены для сопоставления с эффективными тестовыми и установленными аппаратными инструкциями.
Другие способы избежать условий гонки доступны в интерфейсе потоков C11, в частности, mutex-тип mtx_t чтобы взаимно исключить потоки от доступа к критическим данным или критическим разделам кода. Если атомы недоступны, они должны использоваться для предотвращения рас.
атомы и операторы
Доступ к атомным переменным возможен одновременно между различными потоками без создания условий гонки.
/* a global static variable that is visible by all threads */
static unsigned _Atomic active = ATOMIC_VAR_INIT(0);
int myThread(void* a) {
++active; // increment active race free
// do something
--active; // decrement active race free
return 0;
}
Все операции lvalue (операции, которые изменяют объект), разрешенные для базового типа, разрешены и не приводят к условиям гонки между различными потоками, которые обращаются к ним.
- Операции над атомными объектами обычно на порядок медленнее, чем обычные арифметические операции. Это также включает в себя простые операции загрузки или хранения. Поэтому вы должны использовать их только для критических задач.
- Обычные арифметические операции и присвоение, такие как
a = a+1;фактически три операции на : первые нагрузки, а затем сложение и , наконец, магазин.aЭто не гонка бесплатно. Только операцияa += 1;иa++;являются.