8
votes

Tuer une pthead en attente d'une variable de condition

J'ai une pthead en attente d'une variable de condition utilisant pthread_cond_wait () . Il attend que des données d'une structure de file d'attente remplie d'un autre fil. Je veux tuer ce fil, de préférence sans pthread_kill () .

sur Linux et WinPThreads faisant un xxx

est suffisant pour le tuer.

Toutefois, sur OS X, il se bloque sur le pthread_join () appel. Toute suggestion?


1 commentaires

J'utilise SDL alors peut-être que cela confondre le problème. Je sais que SDL fournit sa propre implémentation de fil, et peut-être que je devrais l'utiliser car Pthread / SDL a des interactions bizarres, mais j'ai déjà un peu de code Pthread déjà écrit et je préférerais de le garder de cette façon.


3 Réponses :


0
votes

La première chose que j'essaierais d'essayer de lancer la variable de la variable entre l'annulation et la jointure et que votre vérification de fil cible pour l'annulation explicite explicitement après son retour de la condition Wait.

C'est parce que c'est que c'est que c'est que c'est que c'est que Le fil ne répond pas à l'annulation tant que c'est dans l'état d'attente (ou du tout).

POSIX.1C-2004 (V6) States:

L'état d'annulation et le type de tous les threads nouvellement créés, y compris le fil dans lequel l'appel principal () a été invoqué, doit être pthread_cancel_enable et pthread_cancel_deferred respectivement.

Cela signifie que vous devez vérifier explicitement l'annulation avec pthread_tescancel () .

L'autre option consiste à définir le type d'annulation des threads sur Pthread_cancel_asynchronique Quand il commence à courir, quelque chose comme: xxx

qui est bien sûr en supposant que c'est ce que le problème est. Vous devriez être capable de tester s'il s'agit d'examiner la sortie de cette troisième ligne ci-dessus.

annulation est une demande au fil cible qu'il est libre d'ignorer si elle le souhaite , par opposition au bien plus mauvais pthread_kill () . Je suis un excellent croyant en laissant des threads contrôler leurs propres vies depuis que j'ai trouvé que cela conduit invariablement à moins de problèmes de concurrence.

Misté: En fait, ayant été acheté dans des éditions très précoces de Pthreads, même avant l'intégration dans DCE, je toujours me trouver simplement en utilisant une variable globale pour chaque Fil indiquant quand il doit quitter, avec des mauchets manuellement des mutiles ou des variables de condition pour réveiller les fils. Je suppose que je devrais mettre à jour mes méthodes (ou si je pouvais voir un avantage clair). : -)


3 commentaires

Eh bien, je préférerais certainement avoir une méthode non annulée, mais je n'ai que le fil qui obtient Annuler n'est pas en mesure de conscience qu'il fonctionne dans un fil. J'ai essayé de signaler la variable de condition, mais il se lit ensuite de la file d'attente et des segfaults car il n'y a rien dedans. Bien que cela ait le comportement souhaité de quitter le programme, il semble "juste faux".


BTW, vous ne devriez jamais supposer que, juste parce que vous revenez de cond_wait, il y a du travail disponible. Il est possible pour deux threads en attente de réveil, le premier à obtenir le travail et la seconde ne doit détecter aucun travail disponible et revenir à attendre.


L'état d'annulation différé ne signifie pas que vous devez vérifier explicitement l'annulation avec pthread_tescancel () ; Cette fonction n'est que l'un des nombreux points d'annulation POSIX définit. Vous avez à peu près jamais vouloir annulation asynchrone sauf lorsque vous exécutez des calculs numériques longs avec NO la bibliothèque appelle quelle que soit. Le seul appel de la bibliothèque que vous pouvez apporter alors que l'annulation asynchrone est activée est de désactiver l'annulation asynchrone. :-)



7
votes

pthread_cancel doit réveiller un fil bloqué dans pthread_cond_wait --- C'est l'un des points d'annulation requis. Si cela ne fonctionne pas, quelque chose ne va pas.

La première chose à vérifier est que l'annulation est effectivement activée sur le thread cible - - Appelez explicitement pthread_seCancelState (pthread_cancel_enable et ancien) sur le thread cible pour vous assurer. Si cela ne fonctionne pas, l'annulation est cassée sur votre plate-forme et vous devrez recourir à des alternatives telles que définir un drapeau "Veuillez arrêter maintenant" et signaler la variable de condition.

ne pas Utilisez une annulation asynchrone à moins que vous ne vraiment savez ce que vous faites - cela peut déclencher l'annulation au milieu de toute opération (par exemple au milieu de Configuration d'un cadre de pile d'appel de fonction ou d'exécution d'un destructeur) et peut ainsi laisser votre code dans un état soigneusement incohérent. Ecrire un code async-annulant-Safe est dur .

Incidemment pthread_kill fait pas tue un fil --- il l'envoie un signal.


2 commentaires

J'ai fait pthread_setCancelstate (Pthread_Cancel_Enable, & Oldstate). L'ancien état était pthread_cancel_enable et cela n'avait aucun effet. Je serais très surpris si les Pthreads de Mac OS X étaient cassés, mais je ne suis pas sûr de quoi cela pourrait se tromper, car ce code fonctionne sur Windows et Linux.


Pthreads fonctionne bien, j'ai écrit un petit programme: pthread_cond_tond; pthread_mutex_t verrouillage; vide * tmain (vide *) {pthread_mutex_lock (& ​​verrou); pthread_cond_wait (& Cond, & Serrure); pthread_mutex_unlock (& ​​verrou); } int main () {pthread_t thread; pthread_cond_init (& condy, null); pthread_mutex_init (& verrou, null); pthread_create (& thread, NULL, TMAIN, NULL); Dormir (1); pthread_cancel (fil); pthread_join (fil, null); } Pour le tester et il sort après une seconde. Je dois avoir un autre bogue dans mon code.



6
votes

Avez-vous accès à la file d'attente et contrôlez-vous du schéma d'objet pour des articles en cours? Si tel est le cas, définissez un type d'objet de la file d'attente qui, lorsqu'il est désétabli, indique le fil qui traite l'élément pour quitter gracieusement.

Maintenant, pour arrêter ces threads, postez simplement un certain nombre de ces objets "Quitter" à la tête la tête de la file d'attente correspondant au nombre de threads qui permettent la file d'attente. les fils.

Cela semble beaucoup plus propre que l'option "Nuclear Option" de Pthread_Cancel / Kill.


1 commentaires

C'est vraiment ce que j'ai fait! Merci pour la suggestion, de cette façon, mon thread peut toujours rester dans le noir et courir dans des instances non filetées et ma file d'attente qui est déjà au courant peut prendre soin du saleté et appelle pthread_exit pour tuer le fil.