Suche…


Syntax

  • #ifdef __STDC_NO_ATOMICS__
  • # error this implementation needs atomics
  • #endif
  • #include <stdatomic.h>
  • vorzeichenloser _Atomic Counter = ATOMIC_VAR_INIT (0);

Bemerkungen

Atomics als Teil der C-Sprache ist eine optionale Funktion, die seit C11 verfügbar ist.

Ihr Zweck ist es, einen rennfreien Zugriff auf Variablen zu gewährleisten, die von verschiedenen Threads gemeinsam genutzt werden. Ohne atomare Qualifizierung wäre der Status einer gemeinsam genutzten Variablen undefiniert, wenn zwei Threads gleichzeitig darauf zugreifen. Eine Inkrementierungsoperation ( ++ ) könnte beispielsweise in mehrere Assembler-Anweisungen, einen Lesevorgang, den Zusatz selbst und einen Speicherbefehl aufgeteilt werden. Wenn ein anderer Thread dieselbe Operation ausführen würde, könnten die beiden Befehlssequenzen miteinander verflochten werden und zu einem inkonsistenten Ergebnis führen.

  • Typen: Alle Objekttypen mit Ausnahme von _Atomic können mit _Atomic qualifiziert _Atomic .

  • Operatoren: Alle Operatoren zum Lesen, Ändern und Schreiben (z. B. ++ oder *= ) sind garantiert atomar.

  • Operationen: Es gibt einige andere Operationen, die als generische Funktionen des Typs angegeben sind, z. B. atomic_compare_exchange .

  • Threads: Der Zugriff darauf wird garantiert nicht zu einem Datenrennen führen, wenn von verschiedenen Threads darauf zugegriffen wird.

  • Signalhandler: Atomic-Typen werden als sperrungsfrei bezeichnet, wenn alle Operationen auf ihnen zustandslos sind. In diesem Fall können sie auch verwendet werden, um Zustandsänderungen zwischen dem normalen Steuerfluss und einem Signalhandler zu behandeln.

  • Es gibt nur einen Datentyp, der garantiert atomic_flag : atomic_flag . Dies ist ein minimaler Typ, dessen Operationen dazu bestimmt sind, effiziente Test-and-Set-Hardwareanweisungen abzubilden.

Andere mtx_t zur Vermeidung von Race-Bedingungen sind in der Thread-Schnittstelle von C11 verfügbar, insbesondere ein Mutex-Typ mtx_t , um Threads gegenseitig vom Zugriff auf kritische Daten oder kritische Codeabschnitte auszuschließen. Wenn keine Atomik verfügbar ist, müssen diese verwendet werden, um Rassen zu verhindern.

Atomik und Operatoren

Auf atomare Variablen kann gleichzeitig zwischen verschiedenen Threads zugegriffen werden, ohne dass Race-Bedingungen erstellt werden.

/* 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;
}

Alle lvalue-Operationen (Operationen, die das Objekt ändern), die für den Basistyp zulässig sind, sind zulässig und führen nicht zu Race-Bedingungen zwischen verschiedenen Threads, die auf sie zugreifen.

  • Operationen an atomaren Objekten sind in der Regel um Größenordnungen langsamer als normale Rechenoperationen. Dies umfasst auch einfache Lade- oder Speicheroperationen. Sie sollten sie daher nur für kritische Aufgaben verwenden.
  • Übliche arithmetische Operationen und Zuweisungen wie a = a+1; In der Tat gibt es drei Operationen auf a : zuerst eine Ladung, dann eine Addition und schließlich ein Geschäft. Dies ist nicht frei von Rennen. Nur die Operation a += 1; und a++; sind.


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow