GNU/Linux >> Tutoriels Linux >  >> Linux

Comment faire une incrémentation atomique et récupérer en C?

GCC prend en charge les opérations atomiques :

gcc atomique


CCG __atomic_* intégrés

Depuis GCC 4.8, __sync les éléments intégrés ont été dépréciés au profit du __atomic intégrés :https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/_005f_005fatomic-Builtins.html

Ils implémentent le modèle de mémoire C++ et std::atomic les utilise en interne.

L'exemple de threads POSIX suivant échoue systématiquement avec ++ sur x86-64, et fonctionne toujours avec _atomic_fetch_add .

main.c

#include <assert.h>
#include <pthread.h>
#include <stdlib.h>

enum CONSTANTS {
    NUM_THREADS = 1000,
    NUM_ITERS = 1000
};

int global = 0;

void* main_thread(void *arg) {
    int i;
    for (i = 0; i < NUM_ITERS; ++i) {
        __atomic_fetch_add(&global, 1, __ATOMIC_SEQ_CST);
        /* This fails consistently. */
        /*global++*/;
    }
    return NULL;
}

int main(void) {
    int i;
    pthread_t threads[NUM_THREADS];
    for (i = 0; i < NUM_THREADS; ++i)
        pthread_create(&threads[i], NULL, main_thread, NULL);
    for (i = 0; i < NUM_THREADS; ++i)
        pthread_join(threads[i], NULL); 
    assert(global == NUM_THREADS * NUM_ITERS);
    return EXIT_SUCCESS;
}

Compiler et exécuter :

gcc -std=c99 -Wall -Wextra -pedantic -o main.out ./main.c -pthread
./main.out

Analyse de désassemblage à :Comment démarrer des threads en C ordinaire ?

Testé dans Ubuntu 18.10, GCC 8.2.0, glibc 2.28.

C11 _Atomic

En 5.1, le code ci-dessus fonctionne avec :

_Atomic int global = 0;
global++;

Et C11 threads.h a été ajouté dans la glibc 2.28, qui vous permet de créer des threads en C ANSI pur sans POSIX, exemple exécutable minimal :Comment démarrer des threads en C ordinaire ?


Linux
  1. Comment installer Gcc 4.7 ?

  2. Procédure :Réplication et configuration DRBD

  3. Comment utiliser les variables atomiques en C ?

  4. comment installer gcc 4.9.2 sur RHEL 7.4

  5. Comment définir RPATH et RUNPATH avec GCC/LD ?

Comment installer et configurer SeedDMS

Comment installer GCC Compiler Collection sur CentOS 8 et Rocky Linux 8

Comment installer GCC sur CentOS 7

Comment installer et configurer Grafana

Comment mettre en réseau Ubuntu et Windows 10 ?

Comment installer et utiliser le compilateur GCC sur le système Linux