Wenn Sie GCC auf Ihrer CentOS-Plattform verwenden, können Sie den __atomic
verwenden integrierte Funktionen.
Von besonderem Interesse könnte diese Funktion sein:
— Eingebaute Funktion:bool __atomic_always_lock_free (size_t size, void *ptr)
Diese eingebaute Funktion gibt wahr zurück, wenn Objekte size
sind Bytes generieren immer lock-freie atomare Anweisungen für die Zielarchitektur. size
muss in eine Kompilierzeitkonstante aufgelöst werden und das Ergebnis wird ebenfalls in eine Kompilierzeitkonstante aufgelöst.
ptr
ist ein optionaler Zeiger auf das Objekt, das verwendet werden kann, um die Ausrichtung zu bestimmen. Ein Wert von 0
gibt an, dass eine typische Ausrichtung verwendet werden sollte. Der Compiler kann diesen Parameter auch ignorieren.
if (_atomic_always_lock_free (sizeof (long long), 0))
Atomprimitive C11
http://en.cppreference.com/w/c/language/atomic
_Atomic const int * p1; // p is a pointer to an atomic const int
const atomic_int * p2; // same
const _Atomic(int) * p3; // same
Hinzugefügt in glibc 2.28. Getestet in Ubuntu 18.04 (glibc 2.27) durch Kompilieren von glibc aus dem Quellcode:Mehrere glibc-Bibliotheken auf einem einzigen Host. Später auch getestet auf Ubuntu 20.04, glibc 2.31.
Beispiel angepasst von:https://en.cppreference.com/w/c/language/atomic
main.c
#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>
atomic_int acnt;
int cnt;
int f(void* thr_data)
{
(void)thr_data;
for(int n = 0; n < 1000; ++n) {
++cnt;
++acnt;
// for this example, relaxed memory order is sufficient, e.g.
// atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
}
return 0;
}
int main(void)
{
thrd_t thr[10];
for(int n = 0; n < 10; ++n)
thrd_create(&thr[n], f, NULL);
for(int n = 0; n < 10; ++n)
thrd_join(thr[n], NULL);
printf("The atomic counter is %u\n", acnt);
printf("The non-atomic counter is %u\n", cnt);
}
Kompilieren und ausführen:
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c -pthread
./main.out
Mögliche Ausgabe:
The atomic counter is 10000
The non-atomic counter is 8644
Der nicht-atomare Zähler ist sehr wahrscheinlich kleiner als der atomare, da der Zugriff über Threads hinweg auf die nicht-atomare Variable sehr schnell erfolgt.
Disassemblierungsanalyse unter:Wie starte ich Threads in einfachem C?