Si vous utilisez GCC sur votre plate-forme CentOS, vous pouvez utiliser le __atomic
fonctions intégrées.
Cette fonction pourrait être particulièrement intéressante :
— Fonction intégrée :
bool __atomic_always_lock_free (size_t size, void *ptr)
Cette fonction intégrée renvoie vrai si les objets desize
Les octets génèrent toujours des instructions atomiques sans verrou pour l'architecture cible.size
doit être résolu en une constante de compilation et le résultat est également résolu en une constante de compilation.
ptr
est un pointeur facultatif vers l'objet qui peut être utilisé pour déterminer l'alignement. Une valeur de0
indique qu'un alignement typique doit être utilisé. Le compilateur peut également ignorer ce paramètre.if (_atomic_always_lock_free (sizeof (long long), 0))
Primitives atomiques 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
Ajouté dans la glibc 2.28. Testé dans Ubuntu 18.04 (glibc 2.27) en compilant glibc à partir de la source :Plusieurs bibliothèques glibc sur un seul hôte Testé ultérieurement également sur Ubuntu 20.04, glibc 2.31.
Exemple adapté de :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);
}
Compiler et exécuter :
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c -pthread
./main.out
Sortie possible :
The atomic counter is 10000
The non-atomic counter is 8644
Le compteur non atomique est très probablement plus petit que le compteur atomique en raison de l'accès rapide à travers les threads à la variable non atomique.
Analyse de désassemblage à :Comment démarrer des threads en C ordinaire ?