C Language
Atomics
Ricerca…
Sintassi
-
#ifdef __STDC_NO_ATOMICS__
-
# error this implementation needs atomics
-
#endif
-
#include <stdatomic.h>
- _ contatore asimmetrico = ATOMIC_VAR_INIT (0);
Osservazioni
Atomics come parte del linguaggio C è una funzionalità opzionale disponibile dal C11.
Il loro scopo è quello di garantire l'accesso senza vincoli alle variabili condivise tra diversi thread. Senza qualifica atomica, lo stato di una variabile condivisa non sarebbe definito se due thread accedono contemporaneamente. Ad esempio, un'operazione di incremento ( ++
) potrebbe essere suddivisa in diverse istruzioni di assemblatore, una lettura, l'aggiunta stessa e un'istruzione di memorizzazione. Se un altro thread eseguisse la stessa operazione, le loro due sequenze di istruzioni potrebbero essere intrecciate e portare a un risultato incoerente.
Tipi: tutti i tipi di oggetto, ad eccezione dei tipi di array, possono essere qualificati con
_Atomic
.Operatori: tutti gli operatori di lettura-modifica-scrittura (ad esempio
++
o*=
) su questi sono garantiti per essere atomici.Operazioni: ci sono alcune altre operazioni che sono specificate come funzioni generiche di tipo, ad esempio
atomic_compare_exchange
.Discussioni: l' accesso ad esse è garantito per non produrre corse di dati quando vi si accede da thread diversi.
Gestori del segnale: i tipi atomici sono chiamati senza blocco se tutte le operazioni su di essi sono prive di stato. In tal caso possono anche essere usati per gestire cambiamenti di stato tra il normale flusso di controllo e un gestore di segnale.
Esiste un solo tipo di dati che è sicuro di essere privo di blocco:
atomic_flag
. Questo è un tipo minimale le cui operazioni devono essere mappate su efficienti istruzioni hardware test-and-set.
Altri strumenti per evitare le condizioni di gara sono disponibili nell'interfaccia di thread di C11, in particolare un mutex di tipo mtx_t
per escludere reciprocamente i thread dall'accesso a dati critici o sezioni critiche di codice. Se gli atomici non sono disponibili, questi devono essere usati per prevenire le gare.
atomica e operatori
Le variabili atomiche possono essere consultate contemporaneamente tra diversi thread senza creare condizioni di competizione.
/* 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;
}
Tutte le operazioni di lvalue (operazioni che modificano l'oggetto) consentite per il tipo di base sono consentite e non porteranno a condizioni di competizione tra diversi thread che le accedono.
- Le operazioni sugli oggetti atomici sono generalmente di ordine di grandezza più lente delle normali operazioni aritmetiche. Questo include anche semplici operazioni di carico o negozio. Quindi dovresti usarli solo per compiti critici.
- Operazioni aritmetiche e assegnazioni usuali come
a = a+1;
sono infatti tre operazioni sua
: primo carico, poi aggiunta e infine un negozio. Questa non è una gara libera. Solo l'operazionea += 1;
ea++;
siamo.