IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

POSIX C Discussion :

Probléme desctruction sémaphore


Sujet :

POSIX C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 264
    Points : 104
    Points
    104
    Par défaut Probléme desctruction sémaphore
    Bonjour, j'ai un code source qui permet de gérer une fille d'attente pour accéder à 5 guichets. La ressource critique étant les guichets.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <stdio.h>
    #include <stdlib.h>
    #include "Msem.h"
     
    int guichet ; 
    int pid ;	
     
     
    void Personne(int);
    void Terminaison(void);
     
    main(){
     
    	int i ;
    	guichet = CreerSemaphore(1000,5);
     
    	for(i =0; i<4 ; i++) {
     
    		  if(fork() == 0 ) {
     
    			pid = getpid();
    			Personne(pid);
     
    		  }
     
    	}
    	Terminaison();
    	exit(0);
     
    }
     
    void Personne(int pid){
     
    	P(guichet); 
     
    		printf("le client %d entre dans le guichet \n",pid);
    		fflush(stdout);
    		srand(pid);
    		sleep(rand ()%10);
    		wait(0);		
     
    	V(guichet);
     
    		printf("le client %d libére le guichet \n ", pid) ;
    		fflush(stdout);
    		sleep(2);
    		wait(0);
     
    }
     
    void Terminaison(){
     
    	 DetruireSemaphore(guichet);
    	 printf("la fille d'attente a ete traitee \n"); 
    	 fflush(stdout);
     
    }
    Le problème est dans la procédure Terminaison().
    le message suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     printf("la fille d'attente a ete traitee \n");
    est affiché un peu partout dans le code alors qu'il ne devrai être affiché qu'à la fin de l'exécution.
    le client 9639 entre dans le guichet
    le client 9639 libére le guichet
    le client 9640 entre dans le guichet
    le client 9641 entre dans le guichet
    le client 9642 entre dans le guichet
    la fille d'attente a ete traitee
    [root@domweb TP2]# le client 9642 libére le guichet
    le client 9643 entre dans le guichet
    le client 9644 entre dans le guichet
    le client 9645 entre dans le guichet
    la fille d'attente a ete traitee
    la fille d'attente a ete traitee
    le client 9640 libére le guichet
    le client 9641 libére le guichet
    le client 9650 entre dans le guichet
    la fille d'attente a ete traitee
    le client 9651 entre dans le guichet
    le client 9653 entre dans le guichet
    la fille d'attente a ete traitee
    le client 9643 libére le guichet
    le client 9645 libére le guichet
    le client 9644 libére le guichet
    le client 9651 libére le guichet
    le client 9654 entre dans le guichet
    la fille d'attente a ete traitee
    la fille d'attente a ete traitee
    le client 9655 entre dans le guichet
    le client 9650 libére le guichet
    le client 9656 entre dans le guichet
    la fille d'attente a ete traitee
    la fille d'attente a ete traitee
    le client 9657 entre dans le guichet
    la fille d'attente a ete traitee
    le client 9655 libére le guichet
    la fille d'attente a ete traitee
    le client 9653 libére le guichet
    le client 9654 libére le guichet
    la fille d'attente a ete traitee
    le client 9658 entre dans le guichet
    la fille d'attente a ete traitee
    le client 9656 libére le guichet
    le client 9657 libére le guichet
    la fille d'attente a ete traitee
    la fille d'attente a ete traitee
    le client 9658 libére le guichet
    la fille d'attente a ete traitee
    De plus à la fin de l'exécution je n'ai pas la main alors que l'exécution est fini .
    Est ce que qqn aurai une idée la dessus ?

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 352
    Points : 36 876
    Points
    36 876
    Par défaut
    Bonjour,
    S'il s'agit de sémaphore POSIX, êtes vous sûr qu'ils permettent de synchroniser des objets de type processus crées par fork?
    A ma connaissance, ils n'ont de sens que pour des objets de type "threads" creés par pthread_create
    - W

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 264
    Points : 104
    Points
    104
    Par défaut
    Bah je gére la synchronisation via des sleep et des wait de sort que mes processus soit bien créer.

    Mais normalement les sémaphores s'utilisent avec tous type de processus !!

    je suis dans l'erreur ?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 352
    Points : 36 876
    Points
    36 876
    Par défaut
    Disons que des primitives telles que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    guichet = CreerSemaphore(1000,5);
    ne sont pas standard...

    Elles implémentent ou "encapsulent" je ne sais trop quoi qu'il serait bon de détailler
    -W

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 264
    Points : 104
    Points
    104
    Par défaut
    oui c'est vrai dsl j'avais pas compris.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #include "Msem.h"
    #include <errno.h>
    extern int errno;
     
    int P(int sem)
    {	
    	struct sembuf operat; /*  Une seule opération*/
    	operat.sem_num = 0; /* Un seul sémaphore donc 0 */
    	operat.sem_op = -1; /*  il faut décrémenter de 1 */
    	operat.sem_flg = 0; /*  bloquant si non passant*/ 
    	return(semop(sem, &operat, 1));
    }
     
    int V(int sem)
    {
    	struct sembuf operat; /*  Une seule opération*/
    	operat.sem_num = 0; /* Un seul sémaphore donc 0 */
    	operat.sem_op = 1;  /*  il faut incrémenter de 1 */
    	operat.sem_flg = 0; /*  toujours passant */ 
    	return(semop(sem, &operat, 1));
    }
     
    int CreerSemaphore(key_t cle_ext, int valeur_init)
    {
    	int sem;
    	sem = semget(cle_ext, 1, 0666);
    	if (errno == ENOENT)
    	{
    		sem = semget(cle_ext, 1, 0666|IPC_CREAT); 
    		semctl(sem, 0, SETVAL, valeur_init);
    	}
    	return(sem);}
     
    int DetruireSemaphore(int sem)
    {
    	return(semctl(sem,0, IPC_RMID,0));
    }
    et Msem.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include<sys/ipc.h>
    #include<sys/types.h>
    #include<sys/sem.h>
    int P(int);
    int V(int);
     
     
    int CreerSemaphore(key_t, int);
    int DetruireSemaphore(int sem);

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 352
    Points : 36 876
    Points
    36 876
    Par défaut
    ok, pour ce type de sémaphores.

    Maintenant, relisez le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    main(){
    	int i ;
    	guichet = CreerSemaphore(1000,5); 
    	for(i =0; i<4 ; i++) {
    		  if(fork() == 0 ) {
    			pid = getpid();
    			Personne(pid);
    		  }
    	}
    	Terminaison();
    	exit(0);
    }
    Vous voulez que le père attende la fin de tous les fils avant de libérer le sémaphore...
    Mais il n'y a aucune attente (wait?) , ni de différenciation entre "père" et "fils" pour l'appel à "Terminaison".
    - W

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 264
    Points : 104
    Points
    104
    Par défaut
    j'ai un peu remodifier le programme ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    #include <stdio.h>
    #include <stdlib.h>
    #include "Msem.h"
     
    int guichet ; 
    int pid ;	
     
     
    void Personne(int);
    void Terminaison(void);
     
    main(){
     
    	int i ;
    	int j ; 
    	guichet = CreerSemaphore(guichet,5);
     
    	for(i =0; i<10; i++) {
     
    		  if(fork() == 0 ) {
     
    			pid = getpid();
    			//pid = i ;
    			Personne(pid);
    			wait(0);
    			exit(0);
     
    		  }
     
    	}
     
     
    	/*
    	for ( j = 0; j<10; j++){
     
    		wait(0);
    	}
    	*/
     
    	Terminaison();
     
    }
     
    void Personne(int pid){
     
    	P(guichet); 
     
    		printf("le client %d entre dans le guichet \n",pid);
    		fflush(stdout);
    		srand(pid);
    		sleep(rand ()%10);
    		wait(0);		
     
    	V(guichet);
     
    		printf("le client %d libére le guichet \n ", pid) ;
    		fflush(stdout);
    		sleep(rand ()%10);
    		wait(0);
     
    }
     
    void Terminaison(){
     
    	 DetruireSemaphore(guichet);
    	 printf("la fille d'attente a ete traitee \n"); 
    	 fflush(stdout);
     
    }
    Mais l'exécution est anormale !

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 352
    Points : 36 876
    Points
    36 876
    Par défaut
    A quoi sert d'ajouter
    dans le corps du fils?

    Il s'agit de permettre au père d'attendre que l'ensemble des fils crées par "fork" soient terminés "avant de". Attendre c'est utiliser la primitive wait ou waitpid - dans l'exécution du père! -.
    La question est: comment traduire et maintenir le nombre de fils "vivants" et détecter qu'il devient égal à zéro?.
    - W

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 264
    Points : 104
    Points
    104
    Par défaut
    En prenant en compte les dernières remarque j'ai remodifié mon programme.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #include <stdio.h>
    #include <stdlib.h>
    #include "Msem.h"
     
    int guichet ; 
    int pid ;	
     
     
    void Personne(int);
    void Terminaison(void);
     
    main(){
     
    	int i ;
    	int j ; 
    	int val ; 
    	guichet = CreerSemaphore(1000,5);
     
    	for(i =0; i<10; i++) {
     
    		val = fork(); 
    		  if(val== 0 ) {
     
    			pid = getpid();
    			Personne(pid);
    			exit(0);
    		  }
     
    		  else {
     
    		  }
     
    	}
     
    	for(i = 0; j<10 ;j++ )
    		wait(0);
     
    	Terminaison();
     
    }
     
    void Personne(int pid){
     
    	P(guichet); 
     
    		printf("le client %d entre dans le guichet \n",pid);
    		fflush(stdout);
    		srand(pid);
    		sleep(rand ()%10);
    		wait(0);		
     
    	V(guichet);
     
    		printf("le client %d libére le guichet \n ", pid) ;
    		fflush(stdout);
    		sleep(rand ()%10);
    		wait(0);
    		//exit(0);
     
    }
     
    void Terminaison(){
     
    	 DetruireSemaphore(guichet);
    	 printf("la fille d'attente a ete traitee \n"); 
    	 fflush(stdout);
     
    }

    Mais j'ai un problème cette fois-ci.
    Ma procédure Terminaison ne s'exécute plus du tout !!

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 352
    Points : 36 876
    Points
    36 876
    Par défaut
    Dans l'attente, vous avez écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	for(i = 0; j<10 ;j++ )
    		wait(0);
    sans avoir pris la précaution d'initialiser j

    Personnellement, je commencerai par écrire l'ossature:
    • un père lance N fils qui vivent leur vie,
    • et attend que l'exécution de tous les fils soit terminée pour sortir.


    Ce qui pourrait donner:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <stdio.h>
    #include <stdlib.h>
     
    #define MAX_CHILDS 3
     
    int main(void)
    {
     
    	int i ;
    	int pid;
     
    	for (i =0; i<MAX_CHILDS; i++)
            {
    	        pid = fork();
    		if (pid == 0)  {
    		        sleep(1);
    			exit(0);
    		  }
    	}
            i = 0;
            while (i <MAX_CHILDS)
            {
    	      wait(0);
    	      i++;
    	      printf("i = %d\n", i);
    	}
    }
    Ce code fait quelques hypothèses "implicites" telle que:
    - tous les fils ont bien été crées - pas de test de "success", et attente de la fin d'un nombre de fils supérieure à celui réellement crée.
    - que se passe-t-il si des fils meurent avant que le père appelle wait?

    Une fois que l'ossature vous semblera "robuste", vous pourrez ajouter la viande autour, heu, les opérations sur les sémaphores.
    - W

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 264
    Points : 104
    Points
    104
    Par défaut
    OK OK merci, pour le code .... et oui j'ai fait une petite erreur...

    Je vais tester tous sa et normalement sa devrai aller !

Discussions similaires

  1. problème de sémaphore systemV
    Par hannibal007 dans le forum Administration système
    Réponses: 0
    Dernier message: 04/06/2014, 13h51
  2. problème du sémaphore
    Par saheliano dans le forum POSIX
    Réponses: 4
    Dernier message: 02/12/2010, 19h34
  3. [VB2005] problème de sémaphore
    Par olivier57b dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 07/09/2008, 17h15
  4. problème sur les threads et les sémaphores
    Par ramislebob dans le forum Windows
    Réponses: 1
    Dernier message: 29/06/2006, 11h52
  5. Problème sémaphore POSIX en C++
    Par yakotey dans le forum C++
    Réponses: 5
    Dernier message: 15/12/2005, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo