Utilice la función pthread_join en C
-
Utilice la función
pthread_join
para esperar la terminación del hilo -
Utilice el valor de retorno de la función
pthread_join
para comprobar si hay errores
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
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