Jointure pthread Non bloquante
Je Code l'arrêt d'un serveur multithread.Si tout se passe comme il se doit, tous les threads sortent par leurs propres moyens, mais il y a une petite chance qu'un thread obtienne stuck.In dans ce cas, il serait pratique d'avoir une jointure non bloquante pour que je puisse le faire.
Existe-t-il un moyen de faire un pthread_join non bloquant? Une sorte de jointure chronométrée serait bonne aussi.
Quelque Chose comme ceci:
foreach thread do nb_pthread_join(); if still running pthread_cancel();
Je peux penser à plus de cas où une jointure non-bloking serait utile.
Comme il semble qu'il n'y ait pas une telle fonction, j'ai déjà codé une solution de contournement, mais ce n'est pas aussi simple que je le voudrais.
8 réponses
Comme d'autres l'ont souligné, il n'y a pas de pthread_join non bloquant disponible dans les bibliothèques pthread standard.
Cependant, compte tenu de votre problème déclaré (en essayant de garantir que tous vos threads sont sortis à l'arrêt du programme), une telle fonction n'est pas nécessaire. Vous pouvez simplement faire ceci:
int killed_threads = 0;
for(i = 0; i < num_threads; i++) {
int return = pthread_cancel(threads[i]);
if(return != ESRCH)
killed_threads++;
}
if(killed_threads)
printf("%d threads did not shutdown properly\n", killed_threads)
else
printf("All threads exited successfully");
Il N'y a rien de mal à appeler pthread_cancel sur tous vos threads (terminés ou non), donc appeler cela pour tous vos threads ne bloquera pas et garantira la sortie du thread (propre ou non).
Cela devrait être considéré comme une solution de contournement "simple".
Si vous exécutez votre application sous Linux, vous pourriez être intéressé de savoir que:
int pthread_tryjoin_np(pthread_t thread, void **retval);
int pthread_timedjoin_np(pthread_t thread, void **retval,
const struct timespec *abstime);
Attention, comme le suffixe le suggère, " np "signifie" non portable". Ils ne sont pas standard POSIX, extensions gnu, utiles cependant.
Le mécanisme' pthread_join ' est une commodité à utiliser s'il arrive à faire exactement ce que vous voulez. Il ne fait rien que vous ne pourriez pas faire vous-même, et là où ce n'est pas exactement ce que vous voulez, codez exactement ce que vous voulez.
Il n'y a pas de vraie raison pour laquelle vous devriez réellement vous soucier de savoir si un thread s'est terminé ou non. Ce qui vous intéresse, c'est de savoir si le travail que le thread faisait est terminé. Dire que le thread de faire quelque chose pour indiquer qu'il fonctionne. Comment vous le faire cela dépend de ce qui est idéal pour votre problème spécifique, qui dépend fortement de ce que font les threads.
Commencez par changer votre façon de penser. Ce n'est pas un fil qui se coince, c'est ce que le fil faisait qui se coince.
Si vous développez pour QNX, vous pouvez utiliser la fonction pthread_timedjoin ().
Sinon, vous pouvez créer un thread séparé qui exécutera pthread_join () et alertera le thread parent, en signalant un sémaphore par exemple, que le thread enfant termine. Ce thread séparé peut renvoyer ce qui est obtenu à partir de pthread_join () pour laisser le thread parent déterminer non seulement quand l'enfant se termine, mais aussi quelle valeur il retourne.
La réponse dépend vraiment de la raison pour laquelle vous voulez faire cela. Si vous voulez juste nettoyer les threads morts, par exemple, il est probablement plus facile d'avoir un thread "Dead thread cleaner" qui boucle et se joint.
Je ne suis pas sûr de ce que vous voulez dire exactement, mais je suppose que ce dont vous avez vraiment besoin est un mécanisme d'attente et de notification.
En bref, voici comment cela fonctionne: vous attendez qu'une condition soit satisfaite avec un délai d'attente. Votre attente sera terminée si:
- , Le délai d'attente se produit, ou
- si la condition est remplie.
Vous pouvez l'avoir dans une boucle et Ajouter un peu plus d'intelligence à votre logique. La meilleure ressource que j'ai trouvée pour cela lié à Pthreads est ce tutoriel: POSIX Fils de Programmation (https://computing.llnl.gov/tutorials/pthreads/).
Je suis également très surpris de voir qu'il n'y a pas D'API pour la jointure chronométrée dans Pthreads.
Il N'y a pas de pthread_join
chronométré, mais si vous attendez que d'autres threads soient bloqués dans des conditions, vous pouvez utiliser timed pthread_cond_timed_wait
au lieu de pthread_cond_wait
Vous pouvez pousser un octet dans un tuyau ouvert comme non bloquant pour signaler à l'autre thread quand c'est fait, puis utiliser une lecture non bloquante pour vérifier l'état du tuyau.