Utilisez la fonction pthread_join en C
-
Utilisez la fonction
pthread_join
pour attendre la fin du thread -
Utilisez la valeur de retour de la fonction
pthread_join
pour vérifier les erreurs
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
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