Utilice la función pthread_join en C

Jinku Hu 12 octubre 2023
  1. Utilice la función pthread_join para esperar la terminación del hilo
  2. Utilice el valor de retorno de la función pthread_join para comprobar si hay errores
Utilice la función pthread_join en C

Este artículo explicará varios métodos de cómo utilizar la función pthread_join en C.

Utilice la función pthread_join para esperar la terminación del hilo

Un programa crea subprocesos con la función pthread_create y, por lo general, espera a que terminen con la función pthread_join. pthread_join toma sólo dos argumentos: id de hilo para especificar el hilo esperado y puntero a void* donde se puede almacenar el estado de salida del hilo especificado. Si el usuario no desea recuperar el código de salida del hilo esperado, se debe pasar el valor NULL como segundo argumento. En el siguiente ejemplo, demostramos el programa que crea 8 hilos y ejecuta la función printHello en cada uno de ellos. Entonces, el hilo que llama espera cada hilo con la llamada pthread_join en el bucle. Observe que también almacenamos el código de estado de salida de los subprocesos en la variable retval e imprimimos su valor convirtiéndolo en int. Sin embargo, tenga en cuenta que si el hilo se cancela, el valor PTHREAD_CANCELED se coloca en la dirección 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);
}

Producción :

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

Utilice el valor de retorno de la función pthread_join para comprobar si hay errores

La función pthread_join devuelve un valor entero que también indica diferentes códigos de error en contraste con una función que establece una variable global errno. El valor de retorno es 0 si la llamada fue exitosa y esto garantiza que el hilo dado ha terminado. Si el entero devuelto es igual a EDEADLK, informa que se detectó un interbloqueo. Si se devuelve el valor EINVAL, entonces el hilo dado no se puede unir, y si el valor es igual a ESRCH, indica que no se puede encontrar el ID del hilo dado. En este caso, implementamos una declaración switch para verificar cada caso e imprimir el mensaje correspondiente en 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);
}

Producción :

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

Artículo relacionado - C Thread