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++;
являются.