Utilisez la fonction pthread_join en C

Jinku Hu 12 octobre 2023
  1. Utilisez la fonction pthread_join pour attendre la fin du thread
  2. Utilisez la valeur de retour de la fonction pthread_join pour vérifier les erreurs
Utilisez la fonction pthread_join en C

Cet article vous expliquera plusieurs méthodes d’utilisation de la fonction pthread_join en C.

Utilisez la fonction pthread_join pour attendre la fin du thread

Un programme crée des threads avec la fonction pthread_create, et généralement, il attend qu’ils se terminent avec la fonction pthread_join. pthread_join ne prend que deux arguments: id de thread pour spécifier le thread attendu et pointeur vers void* où l’état de sortie du thread spécifié peut être stocké. Si l’utilisateur ne souhaite pas récupérer le code de sortie du thread en attente, la valeur NULL doit être passée comme second argument. Dans l’exemple suivant, nous montrons le programme qui crée 8 threads et exécute la fonction printHello dans chacun d’eux. Ensuite, le thread appelant attend chaque thread avec l’appel pthread_join dans la boucle. Notez que nous stockons également le code de statut de sortie des threads dans la variable retval et imprimons sa valeur en la convertissant en int. Attention cependant, si le thread est annulé, la valeur PTHREAD_CANCELED est placée à l’adresse retval.

#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif

void *printHello(void *threadid) {
  long tid;
  tid = (long)threadid;
  printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
  return NULL;
}

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

  for (t = 0; t < NUM_THREADS; t++) {
    rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
    if (rc) {
      printf("ERORR; return code from pthread_create() is %d\n", rc);
      exit(EXIT_FAILURE);
    }
  }

  int ret;
  for (t = 0; t < NUM_THREADS; t++) {
    void *retval;
    ret = pthread_join(threads[t], &retval);
    if (retval == PTHREAD_CANCELED)
      printf("The thread was canceled - ");
    else
      printf("Returned value %d - ", (int)retval);
  }
  pthread_exit(NULL);
}

Production:

Hello from thread 0, pthread ID - 140716669929216
Hello from thread 1, pthread ID - 140716661536512
Hello from thread 2, pthread ID - 140716653143808
Hello from thread 3, pthread ID - 140716644751104
Hello from thread 5, pthread ID - 140716627965696
Hello from thread 4, pthread ID - 140716636358400
Hello from thread 6, pthread ID - 140716550387456
Hello from thread 7, pthread ID - 140716541994752

Utilisez la valeur de retour de la fonction pthread_join pour vérifier les erreurs

La fonction pthread_join renvoie une valeur entière qui indique également différents codes d’erreur contrairement à une fonction qui définit une variable globale errno. La valeur de retour est 0 si l’appel a réussi et cela garantit que le thread donné est terminé. Si l’entier retourné est égal à EDEADLK, il signale qu’un blocage a été détecté. Si la valeur EINVAL est retournée, alors le thread donné n’est pas joignable, et si la valeur est égale à ESRCH, cela indique que l’ID de thread donné est introuvable. Dans ce cas, nous implémentons une instruction switch pour vérifier chaque cas et afficher le message correspondant dans stdout.

#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif

void *printHello(void *threadid) {
  long tid;
  tid = (long)threadid;
  printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
  return NULL;
}

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

  for (t = 0; t < NUM_THREADS; t++) {
    rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
    if (rc) {
      printf("ERORR; return code from pthread_create() is %d\n", rc);
      exit(EXIT_FAILURE);
    }
  }

  int ret;
  for (t = 0; t < NUM_THREADS; t++) {
    void *retval;
    ret = pthread_join(threads[t], &retval);
    if (retval == PTHREAD_CANCELED)
      printf("The thread was canceled - ");
    else
      printf("Returned value %d - ", (int)retval);

    switch (ret) {
      case 0:
        printf("The thread joined successfully\n");
        break;
      case EDEADLK:
        printf("Deadlock detected\n");
        break;
      case EINVAL:
        printf("The thread is not joinable\n");
        break;
      case ESRCH:
        printf("No thread with given ID is found\n");
        break;
      default:
        printf("Error occurred when joining the thread\n");
    }
  }
  pthread_exit(NULL);
}

Production:

Hello from thread 0, pthread ID - 140082577512192
Hello from thread 1, pthread ID - 140082569119488
Hello from thread 3, pthread ID - 140082552334080
Hello from thread 5, pthread ID - 140082535548672
Hello from thread 6, pthread ID - 140082527155968
Returned value 0 - The thread joined successfully
Hello from thread 4, pthread ID - 140082543941376
Hello from thread 2, pthread ID - 140082560726784
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Hello from thread 7, pthread ID - 140082518763264
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
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