Le pthread\_join oublié
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 22 — Concurrence et synchronisation
Énoncé
Que se passe-t-il si le fil principal ne joint pas le fil qu'il a créé ?
void* travail(void* arg) {
usleep(50000); /* 50 ms de calcul */
fait = 1;
printf("[fil] j'ai fini, fait = %d\n", fait);
return NULL;
}
int main(void) {
pthread_t f;
pthread_create(&f, NULL, travail, NULL);
/* pas de pthread_join */
printf("[principal] je termine, fait = %d\n", fait);
return 0;
}Corrigé
Mesuré, sans le join :
[principal] je termine, fait = 0
Et c'est tout. La ligne du fil n'apparaît jamais : le fil n'a pas eu le temps d'arriver au printf. Avec le join, les deux lignes sortent, dans l'ordre attendu, et fait vaut .
L'explication est brutale et il faut la connaître : quand main rend la main, le processus se termine, et tous ses fils sont tués sur place, où qu'ils en soient. Il n'y a pas d'attente implicite, pas de message, pas de code de retour non nul. Un travail à moitié fait est abandonné à moitié fait.
Ce n'est pas seulement du travail perdu. Si le fil était en train d'écrire dans un fichier ou de mettre à jour une structure partagée, il laisse un état incohérent — un fichier tronqué, une liste chaînée dont un pointeur ne mène nulle part. C'est la même faute que le free manquant du chapitre chap:langage-c, mais elle porte sur le temps au lieu de la mémoire.
La règle est symétrique de « qui alloue documente qui libère » : qui crée un fil dit qui l'attend. Les deux seules réponses acceptables sont pthread_join et pthread_detach — et la seconde est une promesse explicite que la valeur de retour et l'instant de fin n'intéressent personne.
Le programme sans join est d'ailleurs le plus dangereux des deux, pour la raison de l'exercice 22.1 : sur une machine chargée, ou avec un fil plus court, il afficherait parfois la bonne ligne. Un défaut qui se manifeste selon la charge est un défaut qu'aucun test ne trouve.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.