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

 C Discussion :

Synchronisation des processus


Sujet :

C

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    En recherche d’emploi
    Inscrit en
    Février 2014
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : En recherche d’emploi

    Informations forums :
    Inscription : Février 2014
    Messages : 62
    Points : 36
    Points
    36
    Par défaut Synchronisation des processus
    Bonjour,

    J'ai crée des processus fils (conso/prod) partageant un segment de mémoire en l'occurrence un tableau d'entiers.
    Le nombre de producteurs et consommateurs est passé en paramètre du programme principal (main).

    Seulement, après création d'une ressource partagée, on doit le détruire par la suite i.e lorsqu'on ne l'utilise plus.

    Mon problème est là.
    code1 : Je mets 3 producteurs et 5 consommateurs ça ne marche pas bien évidemment.
    solution :
    code2 : Je les fais boucler indéfiniment cela fonctionne mais à ce moment comment détruire la ressource partagée?

    Voici le code1
    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
     
    void producteur{
        P(caseVide);
        P(mutexP);
        // dépôt de massage
        V(casePleine);
        V(mutexP);
    }
     
    void consommateur{
        P(casePleine);
        P(mutexC);
        // dépôt de massage
        V(caseVide);
        V(mutexC);
    }
     
    /* Programme principal */
    // création de la mémoire partagée
    // Attachement à la ressource partagée
    //création des sémaphores
     
    // Créer les producteurs
    for(i=0; i<nombre_prod; i++){
        if((pid=fork()) == -1)
            die("fork");
        if(pid==0){
            producteur();
            shmdt(...);
            exit(EXIT_SUCCESS);
        }
    }
     
    // Créer les consommateurs
    for(i=0; i<nombre_conso; i++){
        if((pid=fork()) == -1)
            die("fork");
        if(pid==0){
            consommateur();
            shmdt(...);
            exit(EXIT_SUCCESS);
        }
    }
     
    // Attend les processus fils 
    // détruit le sehment de mémoire
    // détruit le sémaphore
    Et le code2, la différence est dans le code producteur-consommateur (boucle infini donc je ne peux détruire la ressource):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Je mets une boucle
    void producteur{
        while(TRUE){
            ...
        }
    }
     
    void consommateur{
        while(TRUE){
            ...
        }
    }
    Une idée?

    Merci.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Sans avoir l'énoncé exact c'est difficile de t'aider (tu nous as donné ce que toi tu en as compris !!!)

    Je pense perso que tes processus fils doivent avoir un début, une vie et une mort. Et donc quand tous les processus qui accèdaient à la zone sont morts (et ça tu peux le détecter) alors tu détruis la zone...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Nouveau membre du Club
    Femme Profil pro
    En recherche d’emploi
    Inscrit en
    Février 2014
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : En recherche d’emploi

    Informations forums :
    Inscription : Février 2014
    Messages : 62
    Points : 36
    Points
    36
    Par défaut
    Salut,

    Merci de m'avoir répondu.

    L'énoncé :
    Producteurs/consommateurs (Synchronisation par sémaphores et mémoire partagée).
    Écrire un programme c dont le nombre de producteurs et consommateurs est passé en paramètre du programme.
    Les messages échangés via le tampon partagé sont tous du même type.

    Je pense perso que tes processus fils doivent avoir un début, une vie et une mort. Et donc quand tous les processus qui accèdaient à la zone sont morts (et ça tu peux le détecter) alors tu détruis la zone...
    Pour savoir que tous les processus sont morts :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int nbfils = nbProducteurs + nbConsommateurs;
         for(i=0; i<nbfils; i++){
             wait(&status_fils);     // Le pere attend les fils
             if(WIFEXITED(status_fils))
                 printf("\nProcessus fils s'est terminé correctement, le code de sortie %d\n", WEXITSTATUS(status_fils));
             else
                 printf("\nProcessus Fils terminé anormalement!\n");
         }
         shmdt((data*)valeurs);  // libère le segment
         shm_delete(idshm);  // Detruit le segment
         sem_delete(semid);  // Detruit le semaphore
    Mais si je fais :
    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
     
    void producteur{
        while(TRUE){
            P(caseVide);
            P(mutexP);
            // dépôt de massage
            V(casePleine);
            V(mutexP);
        }
    }
     
    void consommateur{
        while(TRUE){
            P(casePleine);
            P(mutexC);
            // dépôt de massage
            V(caseVide);
            V(mutexC);
        }
    }
    Si j'ai bien compris le père attendrait indéfiniment que ses fils meurent mais ce code fonctionnerait pour n'importe quel nombre de producteurs et consommateurs.

    Mais si j'enlève la boucle while(TRUE) et que par exemple je mets un nombre de producteurs(3) < au nombre de consommateurs(4) cela ne fonctionne pas car le quatrième consommateur attendrait qu'il y est une case pleine or tous les producteurs sont morts donc ce consommateur va juste attendre qu'une case soit pleine ce qui n'arrivera jamais puisque les producteurs sont morts et le père attendra toujours que tous ses fils meurent pour détruire la ressource partagée.

    Je ne vois pas comment résoudre le problème.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Revaroa Voir le message
    Mais si j'enlève la boucle while(TRUE) et que par exemple je mets un nombre de producteurs(3) < au nombre de consommateurs(4) cela ne fonctionne pas car le quatrième consommateur attendrait qu'il y est une case pleine or tous les producteurs sont morts donc ce consommateur va juste attendre qu'une case soit pleine ce qui n'arrivera jamais puisque les producteurs sont morts et le père attendra toujours que tous ses fils meurent pour détruire la ressource partagée.
    Tu n'as pas bien compris le principe de la production/consommation et des sémaphores..

    Le sémaphore est un "feu rouge" pour protéger une ressource. Chaque processus va donc se comprter de la façon suivante
    • demande d'accès (attente tant que le feu et rouge puis passage quand il passe au vert). Le fait d'accéder fait automatiquement repasser lui-même le feu au rouge (les autres processus attendront donc leur tour)
    • lecture ou écriture suivant que l'on est consommateur ou producteur
    • une fois terminé, on fait repasser le sémaphore au vert. Un autre processus prend alors la main et on repart en attente ou alors on meurt si on n'a plus rien à faire


    Avec ce principe, tu peux avoir plus de consommateurs que de producteurs sans souci. Et tu peux aussi avoir des consommateurs qui n'ont rien à consommer mais qui ne bloquent pas. Si par exemple la ressource est un plat de nouilles, alors
    • chaque producteur qui accède au plat rajoute une nouille
    • chaque consommateur qui accède au plat en mange une

    Donc même s'il y a plus de consommateurs que de producteurs, ben quand il n'y a plus de nouille il n'y en a plus et celui qui accède le fait pour rien mais peut quand-même ressortir pour mourir...

    Et comme le sémaphore est en réalité un compteur (qui bloque quand il est à 0) tu peux jouer de plein de façons
    • mettre le sémaphore à "n" permet alors à "n" processus d'accéder à la zone en même temps (chaque processus qui entre décrémente le compteur, chaque procesuss qui sort l'incrémente)
    • utiliser "n" sémaphores permet de contrôler "n" ressources (la décrémentation/incrémentation affecte les "n" sémaphores en même temps donc un processus X ne peut accéder aux "n" ressources que si elles sont toutes disponibles en même temps)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    En recherche d’emploi
    Inscrit en
    Février 2014
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : En recherche d’emploi

    Informations forums :
    Inscription : Février 2014
    Messages : 62
    Points : 36
    Points
    36
    Par défaut
    Bonjour,

    Voilà j'ai fais :
    Une mémoire partagée contenant une structure de 3 champs.
    - un tableau d'entiers de N éléments.
    - un entier représentant l'indice de dépôt.
    - un entier représentant l'indice de retrait.

    mettre le sémaphore à "n" permet alors à "n" processus d'accéder à la zone en même temps (chaque processus qui entre décrémente le compteur, chaque procesuss qui sort l'incrémente)
    4 sémaphores
    - 1 sémaphore pour les producteurs (mutexP) initialisé à 1.
    - 1 sémaphore pour les consommateurs (mutexC) initialisé à 1.
    - 1 sémaphore pour le nombre de cases pleines (casePleine) initialisé à 0.
    - 1 sémaphore pour le nombre de cases vides (caseVide) initialisé à N.

    Les opérations P et V
    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
     
    void P(int semid, int numSem)
    {
    struct sembuf sempar ;
    sempar.sem_num = numSem ;
    sempar.sem_op = -1 ;
    sempar.sem_flg = 0;
    if (semop(semid, &sempar, 1) == -1)
    perror("Erreur operation P");
    }
     
    void V(int semid, int numSem)
    {
    struct sembuf sempar ;
    sempar.sem_num = numSem ;
    sempar.sem_op = 1 ;
    sempar.sem_flg = 0;
    if (semop(semid, &sempar, 1) == -1)
    perror("Erreur operation P");
    }
    Ensuite, le code producteur et consommateur posté précédemment.
    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
     
    #define MUTEXP 0
    #define MUTEXC 1
    #define CASEPLEINE 2
    #define CASEVIDE 3
     
    void producteur(int semid){
            P(semid, CASEVIDE);
            P(semid, MUTEXP);
            // dépôt de message  
            V(semid, MUTEXP);
            V(semid, CASEPLEINE);
    }
     
    void consommateur(int semid){
            P(semid, CASEPLEINE);
            P(semid, MUTEXC);
            // retrait du message
            V(MUTEXC);
            V(CASEVIDE);
    }
    Le problème c'est qu'il y a blocage?
    Que faut-il changer dans le code?

    Merci.

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Revaroa Voir le message
    4 sémaphores
    - 1 sémaphore pour les producteurs (mutexP) initialisé à 1.
    - 1 sémaphore pour les consommateurs (mutexC) initialisé à 1.
    - 1 sémaphore pour le nombre de cases pleines (casePleine) initialisé à 0.
    - 1 sémaphore pour le nombre de cases vides (caseVide) initialisé à N.

    Le problème c'est qu'il y a blocage?
    Que faut-il changer dans le code?
    Ben t'as franchement rien compris !!!
    Je t'ai dit qu'un sémaphore protégeait une ressource. Quel mot tu ne comprends pas dans cette phrase ???
    Les producteurs c'est une ressource ???
    La ressource c'est le plat de nouilles, ou la zone mémoire. Ou le carrefour qui ne permet que le passage d'une voiture à la fois. Et le sémaphore c'est le feu rouge. Est-ce que tu vas mettre un feu rouge par voiture ou bien un feu rouge par carrefour ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Nouveau membre du Club
    Femme Profil pro
    En recherche d’emploi
    Inscrit en
    Février 2014
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : En recherche d’emploi

    Informations forums :
    Inscription : Février 2014
    Messages : 62
    Points : 36
    Points
    36
    Par défaut
    salut,

    Est-ce que tu vas mettre un feu rouge par voiture ou bien un feu rouge par carrefour ???
    Un feu par carrefour.

    Ok je vais changer mon code.

    Merci beaucoup.

Discussions similaires

  1. ordonnancement et synchronisation des processus
    Par maestroENSI dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 14/11/2010, 17h45
  2. synchronisation des processus
    Par ouadie99 dans le forum C#
    Réponses: 3
    Dernier message: 10/04/2008, 13h55
  3. synchronisation des processus a l'aide des signaux
    Par dammak_info dans le forum Linux
    Réponses: 1
    Dernier message: 29/12/2007, 08h59
  4. Réponses: 2
    Dernier message: 29/03/2007, 17h43
  5. [Synchronisation des processus] Problème du boulanger
    Par Giovanny Temgoua dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 26/02/2005, 12h40

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