Verwendung von die Funktion pthread_join in C

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie die Funktion pthread_join, um auf die Beendigung des Threads zu warten
  2. Verwenden Sie den Rückgabewert der Funktion pthread_join, um nach Fehlern zu suchen
Verwendung von die Funktion pthread_join in C

In diesem Artikel werden verschiedene Methoden zur Verwendung der Funktion pthread_join in C erläutert.

Verwenden Sie die Funktion pthread_join, um auf die Beendigung des Threads zu warten

Ein Programm erstellt Threads mit der Funktion pthread_create und wartet normalerweise darauf, dass sie mit der Funktion pthread_join beendet werden. pthread_join verwendet nur zwei Argumente: Thread-ID, um den warteten Thread anzugeben, und Zeiger auf void*, wo der Exit-Status des angegebenen Threads gespeichert werden kann. Wenn der Benutzer den Exit-Code des warteten Threads nicht abrufen möchte, sollte der Wert NULL als zweites Argument übergeben werden. Im folgenden Beispiel zeigen wir das Programm, das 8 Threads erstellt und in jedem die Funktion printHello ausführt. Dann wartet der aufrufende Thread auf jeden Thread mit dem Aufruf pthread_join in der Schleife. Beachten Sie, dass wir auch den Exit-Statuscode von Threads in der Variablen retval speichern und seinen Wert drucken, indem wir ihn in int umwandeln. Beachten Sie jedoch, dass der Wert PTHREAD_CANCELED an der Adresse retval platziert wird, wenn der Thread abgebrochen wird.

#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);
}

Ausgabe:

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

Verwenden Sie den Rückgabewert der Funktion pthread_join, um nach Fehlern zu suchen

Die Funktion pthread_join gibt einen ganzzahligen Wert zurück, der im Gegensatz zu einer Funktion, die eine globale Variable errno setzt, auch andere Fehlercodes angibt. Der Rückgabewert ist 0, wenn der Aufruf erfolgreich war und dies garantiert, dass der angegebene Thread beendet wurde. Wenn die zurückgegebene Ganzzahl gleich EDEADLK ist, wird gemeldet, dass ein Deadlock erkannt wurde. Wenn der Wert EINVAL zurückgegeben wird, kann der angegebene Thread nicht verbunden werden. Wenn der Wert gleich ESRCH ist, bedeutet dies, dass die angegebene Thread-ID nicht gefunden werden kann. In diesem Fall implementieren wir eine switch-Anweisung, um für jeden Fall zu prüfen und die entsprechende Nachricht an stdout zu drucken.

#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);
}

Ausgabe:

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
Autor: 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

Verwandter Artikel - C Thread