À propos du comportement de pthread_kill ()

J’ai une question sur le comportement de pthread_kill ().

Voici un petit code que j’essaye:

void my_handler1(int sig) { printf("my_handle1: Got signal %d, tid: %lu\n",sig,pthread_self()); //exit(0); } void *thread_func1(void *arg) { struct sigaction my_action; my_action.sa_handler = my_handler1; my_action.sa_flags = SA_RESTART; sigaction(SIGUSR1, &my_action, NULL); printf("thread_func1 exit\n"); } void *thread_func2(void *arg) { int s; s = pthread_kill(tid1_g,SIGUSR1); if(s) handle_error(s,"tfunc2: pthread_kill"); printf("thread_func2 exit\n"); } int main() { int s = 0; pthread_t tid1; s = pthread_create(&tid1,NULL,thread_func1,NULL); if(s) handle_error(s,"pthread_create1"); tid1_g = tid1; printf("tid1: %lu\n",tid1); s = pthread_join(tid1,NULL); if(s) handle_error(s, "pthread_join"); printf("After join tid1\n"); pthread_t tid3; s = pthread_create(&tid3,NULL,thread_func2,NULL); if(s) handle_error(s,"pthread_create3"); s = pthread_join(tid3,NULL); if(s) handle_error(s, "pthread_join3"); printf("After join tid3\n"); return 0; } 

Le résultat obtenu est:

 tid1: 140269627565824 thread_func1 exit After join tid1 my_handle1: Got signal 10, tid: 140269627565824 thread_func2 exit After join tid3 

Ainsi, même si j’appelle pthread_kill () sur un thread déjà terminé, le gestionnaire de ce thread est toujours appelé. Pthread_kill () n’est-il pas supposé renvoyer une erreur (ESRCH) au cas où le thread n’existerait pas?

Toute utilisation (*) de pthread_t pour un thread après sa durée de vie (c’est-à-dire après le retour de pthread_join ou après la fin du thread dans l’état détaché) entraîne un comportement indéfini . Vous ne devez vous attendre à ESRCH si pthread_t est toujours valide, c’est-à-dire si vous n’avez pas encore rejoint le fil de discussion. Sinon, tous les paris sont ouverts.

Remarque: Par “utiliser” (*), j’entends le transmettre à une fonction pthread_ dans la bibliothèque standard. Autant que je sache, il suffit de l’affecter à une autre variable pthread_t ou de la transmettre d’une manière ou d’une autre entre vos propres fonctions sans “utiliser”, cela ne donne pas UB.

Selon ce fil SO , le fait de transmettre un signal à un fil déjà mort (uniquement si le fil a été rejoint ou quitté) entraîne un comportement indéfini!

EDIT : un fil qui cite clairement la dernière spécification POSIX qui indique que le comportement est indéfini a été trouvé. Merci R .. pour les bons pointeurs!

La question posée ici (Comment déterminer si un pthread est toujours en vie) a été marquée comme étant en double dans cette question.

Mais je pense que cet article clarifie simplement le comportement de pthread_kill et confirme qu’il ne garantit pas le comportement correct si pthread_kill est appelé avec l’ID qui n’est plus valide. Par conséquent, pthread_kill ne peut pas être utilisé pour savoir si le thread est actif ou non, comme si le thread avait déjà été rejoint, l’ID n’aurait pas été valide ou aurait été réutilisé et il en est de même s’il a été détaché comme les ressources l’ont peut-être été. a été récupéré si le fil était terminé.

Donc, pour déterminer si le thread est vivant (la question est spécifiquement posée pour les threads joignables), je pourrais penser à une seule solution comme ci-dessous:

Utilisez des données / mémoires globales accessibles aux deux threads et stockez le statut de retour / sortie du thread dont le statut doit être déterminé ici. D’autres threads peuvent vérifier ces données / locatin pour obtenir son statut. (Évidemment, cela suppose que le thread se termine normalement, c’est-à-dire qu’il soit joint ou détaché).

Par exemple:

 Have a global bool named as "bTerminated" initialized with "FALSE" and in the handler function of this thread either make it as "TRUE" before returning or modify it once it is returned to the caller (ie where you have called `pthread_join` for this thread). Check for this variable in any other threads where you want to know if this thread is alive. Probably it will be straight to implement such a logic which fits into your original code.