GNU/Linux >> Linux Esercitazione >  >> Linux

Come eseguire un incremento atomico e recuperare in C?

GCC supporta le operazioni atomiche:

gcc atomiche


GCC __atomic_* integrati

A partire da GCC 4.8, __sync i built-in sono stati deprecati a favore del __atomic built-in:https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/_005f_005fatomic-Builtins.html

Implementano il modello di memoria C++ e std::atomic li utilizza internamente.

Il seguente esempio di thread POSIX fallisce coerentemente con ++ su x86-64 e funziona sempre con _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;
}

Compila ed esegui:

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

Analisi di disassemblaggio su:Come posso iniziare i thread in C semplice?

Testato in Ubuntu 18.10, GCC 8.2.0, glibc 2.28.

C11 _Atomic

In 5.1, il codice precedente funziona con:

_Atomic int global = 0;
global++;

E C11 threads.h è stato aggiunto in glibc 2.28, che consente di creare thread in ANSI C puro senza POSIX, esempio eseguibile minimo:Come posso avviare thread in C normale?


Linux
  1. Come installare Gcc 4.7?

  2. Procedura:replica e configurazione DRBD

  3. Come usare le variabili atomiche in C?

  4. come installare gcc 4.9.2 su RHEL 7.4

  5. Come impostare RPATH e RUNPATH con GCC/LD?

Come installare e configurare SeedDMS

Come installare la raccolta del compilatore GCC su CentOS 8 e Rocky Linux 8

Come installare GCC su CentOS 7

Come installare e configurare Grafana

Come collegare in rete Ubuntu e Windows 10?

Come installare e utilizzare il compilatore GCC su sistema Linux