Поиск…


Синтаксис

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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow