GNU/Linux >> Tutoriels Linux >  >> Linux

Comment utiliser les variables atomiques en C ?

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 de size 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 de 0 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 ?


Linux
  1. Comment utiliser BusyBox sous Linux

  2. Comment j'utilise cron sous Linux

  3. Comment utiliser FIND sous Linux

  4. Comment utiliser Nginx pour rediriger

  5. Comment utiliser dos2unix ?

Comment utiliser des variables dans Ansible Playbook

Comment utiliser des variables dans les scripts Shell

Comment utiliser Instagram dans le terminal

Comment utiliser la commande PS

Comment utiliser la commande TOP

Comment utiliser FTP