C Language
Kernfysica
Zoeken…
Syntaxis
-
#ifdef __STDC_NO_ATOMICS__
-
# error this implementation needs atomics
-
#endif
-
#include <stdatomic.h>
- unsigned _Atomic counter = ATOMIC_VAR_INIT (0);
Opmerkingen
Atomics als onderdeel van de C-taal zijn een optionele functie die beschikbaar is sinds C11.
Hun doel is om racevrije toegang te garanderen tot variabelen die worden gedeeld tussen verschillende threads. Zonder atomaire kwalificatie zou de status van een gedeelde variabele niet worden gedefinieerd als twee threads tegelijkertijd toegang hebben. Een incrementele bewerking ( ++
) kan bijvoorbeeld worden opgesplitst in verschillende assemblerinstructies, een leesopdracht, de toevoeging zelf en een winkelinstructie. Als een andere thread dezelfde bewerking zou uitvoeren, zouden hun twee instructiesequenties met elkaar kunnen worden verweven en tot een inconsistent resultaat kunnen leiden.
Typen: Alle objecttypen met uitzondering van
_Atomic
kunnen worden gekwalificeerd met_Atomic
.Operators: Alle read-modify-write-operatoren (bijv.
++
of*=
) op deze zijn gegarandeerd atomair.Bewerkingen: er zijn enkele andere bewerkingen die worden gespecificeerd als generieke
atomic_compare_exchange
, bijvoorbeeldatomic_compare_exchange
.Threads: Toegang tot hen is gegarandeerd geen data race produceren wanneer ze worden benaderd door verschillende threads.
Signaalhandlers: Atoomtypen worden lock-free genoemd als alle bewerkingen erop stateless zijn. In dat geval kunnen ze ook worden gebruikt om statusveranderingen tussen normale besturingsstroom en een signaalbehandelaar af te handelen.
Er is slechts één gegevenstype dat gegarandeerd vrij is:
atomic_flag
. Dit is een minimaal type wiens bewerkingen zijn bedoeld om te worden toegewezen aan efficiënte test-en-set hardware-instructies.
Andere middelen om race-omstandigheden te voorkomen zijn beschikbaar in de thread-interface van C11, met name een mutex-type mtx_t
om threads wederzijds uit te sluiten van toegang tot kritieke gegevens of kritische secties van code. Als er geen atomen beschikbaar zijn, moeten deze worden gebruikt om races te voorkomen.
atomica en operatoren
Atomaire variabelen kunnen gelijktijdig worden benaderd tussen verschillende threads zonder raceomstandigheden te creëren.
/* 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-bewerkingen (bewerkingen die het object wijzigen) die zijn toegestaan voor het basistype zijn toegestaan en zullen niet leiden tot race-omstandigheden tussen verschillende threads die toegang hebben tot deze.
- Bewerkingen op atomaire objecten zijn in het algemeen orden van grootte langzamer dan normale rekenkundige bewerkingen. Dit omvat ook eenvoudige laad- of opslagbewerkingen. U moet ze dus alleen gebruiken voor kritieke taken.
- Gebruikelijke rekenkundige bewerkingen en toewijzingen zoals
a = a+1;
zijn in feite drie bewerkingen opa
: eerst een lading, dan toevoeging en ten slotte een winkel. Dit is niet racevrij. Alleen de bewerkinga += 1;
ena++;
zijn.