2017-08-29 14 views
1

Il existe deux sémaphores et deux processus. "p1sem" indique que process1 attend sur ce sémaphore et process2 publie ce sémaphore. "p2sem" fait le contraire. Les deux processus initialisent les valeurs à 0 (si elles n'ont pas été créées)Problème bizarre avec les sémaphores POSIX

Ainsi, process1 exécute deux sessions d'ouverture et de suppression de ces deux sémaphores. process2 ne s'exécute que pour une session mais est supposé être appelé à nouveau pour épuiser la prochaine session de process1. C'est ce que le code ressemble à:

process2:

#include <semaphore.h> 
#include <fcntl.h> 

int main(){ 
    sem_t *waitSem = sem_open("p2sem", O_CREAT, 0666, 0); 
    sem_t *postSem = sem_open("p1sem", O_CREAT, 0666, 0); 

    // tic for a cycle 
    sem_post(postSem); 
    sem_wait(waitSem); 

    // close and exit 
    sem_close(waitSem); 
    sem_close(postSem); 
    sem_unlink("p2sem"); 
    sem_unlink("p1sem"); 
} 

process1:

#include <semaphore.h> 
#include <fcntl.h> 

int main() { 
    for(int i = 0; i < 2; i++) { 

     // create sems 
     sem_t *waitSem = sem_open("p1sem", O_CREAT, 0666, 0); 
     sem_t *postSem = sem_open("p2sem", O_CREAT, 0666, 0); 

     // tic for a cycle 
     sem_post(postSem); 
     sem_wait(waitSem); 

     // close and exit 
     sem_close(waitSem); 
     sem_close(postSem); 
     sem_unlink("p2sem"); 
     sem_unlink("p1sem"); 
    } 
} 

Pour process1 de continuer, process2 doit afficher le p1sem. Idem pour process2, qui ne peut continuer que si process1 publie son p2sem. Cela peut ressembler à une sorte d'impasse, mais les messages arrivent avant les attentes, ce qui ne devrait pas poser de problème.

Lorsque process1 démarre en premier, puis j'appelle process2 deux fois, tout fonctionne correctement.

Toutefois, si process2 démarre en premier, la première session fonctionne correctement, mais lorsque process2 est appelé à nouveau, les deux processus se bloquent. Pour autant que je comprenne, il n'y a aucune raison que cela se produise. Quand je débogue, les valeurs des sémaphores au moment de la suspension sont vis-à-vis pour chaque processus (ie p1sem a la valeur 0 au processus1 mais la valeur 1 au processus 2. Idem pour p2sem.) J'ai joint une image de mon gdb (look à __align = pour la valeur des sémaphores, le grand nombre positif indique un négatif -1 qui est - # de processus en attente sur ce sémaphore, au moins selon http://man7.org/linux/man-pages/man3/sem_getvalue.3.html) Vous pouvez également jouer en appelant sem_post et sem_wait via gdb mais vous verrez que quel que soit le processus que vous appelez cela, cela n'affecte pas les valeurs des sémaphores de l'autre.

/dev/shm contient sem.p1sem et sem.p2sem. Si les gens veulent tester cela, alors pour redémarrer le processus, vous devez supprimer ces sémaphores avec rm sem.p1sem sem.p2sem

Est-ce que quelqu'un le comprend?

enter image description here

Répondre

1

Si vous lancez "PROC2" puis "PROC1", il ressemble à:

  • "PROC1" est élu il délie sémaphores, puis créer les nouvelles,
  • alors "proc2" est élu et dissocie les sémaphores nouvellement créés,
  • ainsi une nouvelle instanciation de "proc2" crée de nouveaux sémaphores sans rapport avec les précédents. Ceci est spécifié par sem_open:

Si un processus rend des appels répétés à sem_open(), avec le même nom l'argument , le même descripteur est renvoyé pour chaque appel réussi, à moins sem_unlink() a été appelé sur le sémaphore dans l'intervalle.

« PROC1 » est alors bloqué en attente sur un sémaphore qui est plus accessible par tout autre procédé.

+0

Merci pour la réponse! Je ne comprends toujours pas la 3ème étape. Le fait est que ces sémaphores sont nommés, donc à moins que je manque quelque chose, ils ne devraient pas être sans rapport avec les précédents puisqu'ils ont le même nom (p1sem, p2sem) Aussi, le 1er, quand proc1 se déconnecte, il ne supprime pas les sémaphores du système d'exploitation, car ils sont toujours accessibles depuis proc2. Alors quand il va créer les "nouveaux", ils ne sont pas vraiment nouveaux, le sem_open devrait retourner les sémaphores qui existent déjà là. (Le drapeau O_CREAT signifie qu'il devrait créer le sémaphore SI il n'existe pas) – burnedWood

+1

Hélas non, c'est juste comme des fichiers, si vous l'avez supprimé et ensuite recréer c'est des fichiers différents. Citation du manuel de 'sem_open' * Si un processus fait des appels répétés à sem_open(), avec le même nom argu- ment, le même descripteur est retourné pour chaque appel réussi, sauf si sem_unlink() a été appelé dans le sémaphore l'intérim. * –

+0

Merci Jean-Baptiste, je comprends maintenant! – burnedWood