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.

21
demandé sur pseudosavant 2008-09-16 19:18:36

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".

1
répondu Frosty 2008-09-17 14:25:42

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.

Lien vers la page de manuel

21
répondu yves Baumes 2017-10-26 21:25:57

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.

10
répondu David Schwartz 2011-09-23 23:28:49

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.

2
répondu dmityugov 2008-09-17 08:55:06

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.

1
répondu raldi 2008-09-16 15:24:51

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.

1
répondu Srikanth 2008-09-16 15:50:08

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

1
répondu shodanex 2008-09-17 08:15:58

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.

0
répondu Doug T. 2008-09-16 15:20:16