Utilisez la bibliothèque de threads C11 en C

Jinku Hu 12 octobre 2023
  1. Utilisez la fonction thrd_create pour créer un nouveau thread et exécuter la routine donnée en C
  2. Utilisez la fonction thrd_join pour attendre le thread donné en C
Utilisez la bibliothèque de threads C11 en C

Cet article explique plusieurs méthodes d’utilisation de la bibliothèque de threads C11 dans C.

Utilisez la fonction thrd_create pour créer un nouveau thread et exécuter la routine donnée en C

La prise en charge des threads était attendue depuis longtemps dans la spécification du langage C standard et a finalement été réalisée en C11. Auparavant, l’API des threads POSIX était utilisée comme outil principal pour utiliser la programmation multi-thread. Étant donné que le C11 fournissait une interface plus standard pouvant être utilisée sans dépendances de plate-forme, il a été recommandé d’utiliser l’API du langage ISO plutôt que la version POSIX. Bien que les deux API ne correspondent pas dans leurs prototypes de fonctions, les principales fonctionnalités sont pour la plupart similaires. Dans l’exemple suivant, nous montrons le scénario simple où quatre threads sont lancés pour exécuter la fonction printHello puis se terminent sans rejoindre le thread principal.

thrd_create prend trois arguments,

  1. Le premier est un pointeur vers l’identificateur de thread.
  2. Le deuxième argument est de type - thrd_start_t, qui est simplement typedef pour un prototype de pointeur de fonction.
  3. Le troisième paramètre spécifie un argument qui peut être passé à la fonction.

Les codes d’état de retour de thrd_create sont définis à l’aide des valeurs enum: thrd_success, thrd_nomem et thrd_error.

#include <stdio.h>
#include <stdlib.h>
#include <threads.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

void *printHello(void *thr_id) {
  long tid;
  tid = (long)thr_id;
  printf("Hello There! thread #%ld, pthread ID - %lu\n", tid, thrd_current());
  thrd_exit(EXIT_SUCCESS);
}

int main(int argc, char const *argv[]) {
  thrd_t threads[NUM_THREADS];
  int rc;
  long t;

  for (t = 0; t < NUM_THREADS; t++) {
    rc = thrd_create(&threads[t], (thrd_start_t)printHello, (void *)t);
    if (rc == thrd_error) {
      printf("ERORR; thrd_create() call failed\n");
      exit(EXIT_FAILURE);
    }
  }
  thrd_exit(EXIT_SUCCESS);
}

Production:

Hello There! thread 0, pthread ID - 140215498864384
Hello There! thread 1, pthread ID - 140215490471680
Hello There! thread 3, pthread ID - 140215473686272
Hello There! thread 2, pthread ID - 140215482078976

Utilisez la fonction thrd_join pour attendre le thread donné en C

thrd_join est un analogue de la fonction pthread_join, et il bloque le thread actuel jusqu’à ce que le thread donné termine l’exécution. Il prend deux arguments: l’identificateur de thread et le pointeur int indiquant l’emplacement où le code d’état de retour peut être stocké en option si l’utilisateur fournit l’adresse valide. Si le thrd_join est appelé sur un thread qui était déjà détaché ou joint, le résultat est un comportement indéfini. La fonction renvoie les valeurs correspondant à thrd_success ou thrd_error.

L’exemple de code suivant implémente le scénario où quatre threads incrémentent la variable de type atomic_int. Enfin, le thread principal qui attend que les autres finissent imprime la valeur de somme finale de counter.

#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <threads.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

atomic_int counter = 0;

enum { MAX_ITER = 1000 };

void *printHello(void *thr_id) {
  long tid;
  tid = (long)thr_id;
  printf("thread %ld started incrementing ID - %lu\n", tid, thrd_current());

  for (int i = 0; i < MAX_ITER; ++i) {
    counter += 1;
  }

  return NULL;
}

int main(int argc, char const *argv[]) {
  thrd_t threads[NUM_THREADS];
  int rc;
  long t;

  for (t = 0; t < NUM_THREADS; t++) {
    rc = thrd_create(&threads[t], (thrd_start_t)printHello, (void *)t);
    if (rc == thrd_error) {
      printf("ERORR; thrd_create() call failed\n");
      exit(EXIT_FAILURE);
    }
  }

  for (t = 0; t < NUM_THREADS; t++) {
    thrd_join(threads[t], NULL);
  }
  printf("count = %d\n", counter);

  thrd_exit(EXIT_SUCCESS);
}

Production:

thread 0 started incrementing ID - 139729818216192
thread 2 started incrementing ID - 139729801430784
thread 3 started incrementing ID - 139729793038080
thread 1 started incrementing ID - 139729809823488
count = 4000
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Article connexe - C Thread