Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1364 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Sémaphore Posix anonyme - comportement inexpliqué

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Sémaphore Posix anonyme - comportement inexpliqué

n°1831886
xelag
Posté le 28-12-2008 à 01:57:07  profilanswer
 

Bonjour,
J'ai un souci avec les sémaphore Posix anonyme utilisés dans la synchronisation de threads. Je tiens d'abords à poser le contexte.. attention, accrochez-vous!
 
Mes threads permettent d'activer certaines sous-routines qui sont chacune liées à un flag. Ceux-ci sont testés dans une boucle infinie exécutée dans le thread qui est bloqué à chaque boucle par un sémaphore (sem_wait()). Avec le code, ce sera peut-être plus clair :
 

Code :
  1. //fonction exécutée dans un thread détaché du fil d'exécution principal du programme
  2. void maFonctionThreadee()
  3. {
  4.   while(true)
  5.   {
  6.     if(maSousRoutine1_activee)
  7.     {
  8.       maSousRoutine1_activee = false;
  9.       maSousRoutine1_Privee();
  10.     }
  11.     else if(maSousRoutine2_activee)
  12.     {
  13.       maSousRoutine2_activee = false;
  14.       maSousRoutine2_Privee();
  15.     }
  16.     //...
  17.    
  18.     //arrête le thread jusqu'à la prochaine activation
  19.     sem_wait(&monSemaphore);
  20.   }
  21. }
  22. //fonction public appelée depuis le fil d'exécution principal du programme
  23. void MaSousRoutine1_Public()
  24. {
  25.   maSousRoutine1_activee = true;
  26.   //activation de la boucle dans la fonction "threadée"
  27.   sem_post(&monSemaphore);
  28. }
  29. //fonction privée, appelée depuis la boucle de la fonction "threadée"
  30. void maSousRoutine1_Privee()
  31. {
  32.   //code traitement
  33. }


 
Je dois interrompre ce thread de manière asynchrone.  
 
J'arrive à le faire car lors de l'initialisation du thread, je paramètre l'activation des interruptions avec :

Code :
  1. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  2. pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);


Et je l'interromps avec l'appel à la fonction :

Code :
  1. pthread_cancel(referenceAuThread);


 
Le thread s'interrompt bien.
Lorsque je réinitialise le thread, je réinitialise en premier les flags d'activation relatifs aux sous-routines, ainsi que le sémaphore utilisé pour bloquer/activer la boucle de la manière suivante :

Code :
  1. //destruction de l'ancien sémaphore
  2. sem_destroy (&monSemaphore);
  3. //initialisation du nouveau sémaphore
  4. //(initialiser à 0, ainsi au premier sem_wait, il attendra jusqu'à qu'on active
  5. //une des sous-routine et qu'un sem_post soit effectué).
  6. sem_init(&monSemaphore, 0, 0);


Ensuite, l'initialisation du thread :

Code :
  1. // le thread est detaché
  2. pthread_attr_setdetachstate(&pthread_attr_t,PTHREAD_CREATE_DETACHED);
  3. //initialise le thread et le lance dans la méthode maFonctionThreadee
  4. pthread_create(&referenceAuThread, &pthread_attr_t, maFonctionThreadee)


 
 
Voilà, donc pour en arriver au fait.. J'arrive à interrompre mes threads, à les réinitialiser et à les relancer. Cependant, parfois de manière inattendue, après avoir relancer mes threads, lorsque j'effectue un sem_post sur le sémaphore monSemaphore pour activer la boucle, celui-ci s'incrémente bien (j'ai vérifié avec la fonction sem_getvalue()), mais le thread en attente sur le sem_wait dans la boucle infinie ne se débloque pas...
 
J'ai lu dans la doc MAN, que de faire un sem_destroy(&monSemaphore) alors que ce sémaphore a des threads en attente, peut amener un comportement indéfini :

Citation :

“Destroying a semaphore that other processes or threads are currently blocked on (in sem_wait(3)) produces undefined behaviour.”

Linux MAN page  
 
8O
 
Est-ce que cela pourrait-il être la cause de mon problème? Pourtant, j'ai l'impression de tout réinitialiser proprement et deux fois sur trois, cela fonctionne très bien.. Vive les bugs de concurrence!
 
Merci d'avance pour votre aide, j'en ai un grand besoin! :?
Alex

mood
Publicité
Posté le 28-12-2008 à 01:57:07  profilanswer
 

n°1831892
Mackila
Posté le 28-12-2008 à 09:19:37  profilanswer
 

Code :
  1. void maFonctionThreadee()
  2. {
  3.   while(!maConditionDArretDuThread)
  4.   {
  5. //......
  6. void MaSousRoutineDArret_Public()
  7. {
  8.   maConditionDArretDuThread = true ;
  9.   sem_post(&monSemaphore);
  10. }


 
 :??:  
 
Comme ca t'as pas à détruire/recontruire ton objet de synchro, le thread se sort proprement, toussa ? (c'est à la louche, je connais pas les API utilisées ici...)

n°1831905
xelag
Posté le 28-12-2008 à 12:16:43  profilanswer
 

Oui, mais j'ai des sous-routines qui prennent du temps à s'exécuter. Je dois pouvoir interrompre ces traitements instantanément.

n°1831908
Mackila
Posté le 28-12-2008 à 12:54:24  profilanswer
 

Tuer des threads, c'est comme tuer des chatons, cay mal :o
 
Si ton traitement dure longtemps, bah tu peux essayer de te débrouiller pour que le dit traitement teste de temps en temps la condition maConditionDArretDuThread. Si ce n'est pas possible, bah c'est dommage (mais dans ce cas, tu peux tuer le thread sans qu'il ne soit en train d'attendre dans son sem_wait(), et donc t'as pas le problème de comportement indéfini précisé dans la doc... - fais quand même gaffe aux ressources utilisées par ton traitement dans le thread et qu'il ne pourrait libérer en cas d'arrêt de brutasse...)

n°1831915
xelag
Posté le 28-12-2008 à 14:01:27  profilanswer
 

J'ai obtenu l'explication de ce comportement indéfini sur un autre forum en anglais :
http://www.linuxforums.org/forum/l [...] post654519
 
Une manière plus propre que d'utiliser un booléen est l'utilisation d'interruption différée avec l'utilisation de point d'interruption "Cancellation points".
 
Merci quand même pour votre aide,
Alexandre

n°1831957
Mackila
Posté le 28-12-2008 à 18:36:23  profilanswer
 

Ouaip enfin ca revient au même, ils disent juste que tuer des threads, c'est mal, et te disent de mettre ce qu'il faut dans le code de ton thread pour qu'il soit capable de se fermer proprement tout seul si besoin.

n°1831958
xelag
Posté le 28-12-2008 à 18:41:59  profilanswer
 

Mackila a écrit :

Ouaip enfin ca revient au même...


Il y a une différence entre tester un booléen homemade et utilisé des fonctionnalités POSIX prévus pour faire cela proprement comme tu dis..


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Sémaphore Posix anonyme - comportement inexpliqué

 

Sujets relatifs
Reprendre la bonne valeur dans une fonction anonyme[C] POSIX message queues : #define MQ_MAXMSG 10 ???
Comportement étrange avec IE / Firefox OK[PHP][résolu] Include et global -- comportement étrange --
[Plone] Customisation du comportement d'un lienDebug d'ASP.net : Comportement de Visual Studio et IIS
shmget: comportement que je ne comprends pasPerte de focus clavier inexpliqué, aide bienvenue !
Comportement d'une boucle sur un tableau modifié dans la boucle 
Plus de sujets relatifs à : Sémaphore Posix anonyme - comportement inexpliqué


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR