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 :

Implementation producteur/consommateur cas famine


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    fdf
    Inscrit en
    Novembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : fdf

    Informations forums :
    Inscription : Novembre 2014
    Messages : 20
    Par défaut Implementation producteur/consommateur cas famine
    Bonjour,

    Après avoir implémenté l'algo du producteur consommateur pour la communication entre deux processus avec les semaphores (pas IPC V) le consommateur reste bloqué
    dès le début au niveau de :
    if(sem_wait(&plein))

    Il reste bloqué car sem_t plein a été initialisé à 0. Les sempahores sont dans une memoire partagée.

    Pour éviter le bloquage du consommateur je dois créer un boolen dans le shm : bool peux_lire

    Vue que les deux processus tourne en même temps, dès que le producteur a fini de remplir le buffer avec au moins une production il met le boolen à true
    pendant ce temps le consommateur attendait dans sa fonction lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    lire_depuis(shared_memory* shm) {
      do {
        while(!peux_lire);
        if(sem_wait (&plein)) ==-1)... etc
        //algo classique
    } while(shm-> n > 0);  //au moins une production  à lire.
    shm-> n c'est le nombre de donnée écrite dans le buffer du shm.

    Est-ce normal que je dois utiliser une telle boucle (while(! peux_lire))
    pour le consommateur.
    ou alors je dois utiliser sleep(1) juste avant la fonction lire_dans(shm)
    pour que le producteur ait eu le temps.
    Mais cette dernière solution ne respecte pas la règle des semaphores comme quoi on doit faire des suppositions sur la vitesse des processus.

    Merci

  2. #2
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Ton algo est curieux. Si je comprend bien, le consommateur est bloqué tant que le producteur n'a pas écrit ses "n" messages ? Le consommateur attend que le buffer soit rempli ?
    Tu sembles utiliser le sémaphore comme un mutex.
    Voici une possibilité :
    1. sémaphore : initialiser sa valeur à 0.
    2. SHM : elle contient N cases pour stocker N messages. Elle contient aussi un entier i_p modifié exclusivement par le producteur pour savoir dans quelle case écrire son message. Elle contient un autre entier i_c exclusivement utilisé par le consommateur pour savoir dans quelle case est le prochain message à lire. Au début, i_p=0, i_c=0. i_p sera toujours "devant" i_c. La SHM est utilisée comme une file : premier entré, premier sortie. i_c ne doit jamais dépasser i_p.
    3. producteur : si la valeur du sémaphore est inférieur à N, alors écrire le message dans la case i_p puis incrémenter i_p. (si i_p >= N, alors i_p=0). Enfin incrémenter le sémaphore.
    4. consommateur : si la valeur du sémaphore est supérieure à 0, alors lire le message dans la case i_c, incrémenter i_c. (si i_c >= N, alors i_c=0). Enfin décrémenter le sémaphore.

    Pourquoi n'utilises-tu pas une file de messages IPC ? C'est exactement fait pour ça (sauf si c'est un exercice sur SHM/sémaphore, évidemment).
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  3. #3
    Membre averti
    Homme Profil pro
    fdf
    Inscrit en
    Novembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : fdf

    Informations forums :
    Inscription : Novembre 2014
    Messages : 20
    Par défaut
    Dans ton algo il faudrait un autre sémaphore mutex initialisé à 0 pour contrôler l'accès au shm non ?
    J'ai implementé ton algo et le consommateur quitte direct vue que ton semaphore que j'ai nommé quantité vaut 0.

    Ici buff contient les donné de taille n reçu par le producteur à écrire dans le shm
    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
    void write_answer(shared_mem *shm, char buff[BUFFER_SIZE], ssize_t n) {
      int quantite; 
      sem_getvalue(&shm -> quantite, &quantite);
       if(quantite < BUFFER_SIZE) {
         if (sem_wait(&shm -> mutex) == -1) {
            perror("sem_wait");
    	exit(EXIT_FAILURE);
         }
         for(int i = 0; i < n;  ++i) {
           shm -> buffer[i] = buff[i];
           shm -> head += 1;
           if(shm -> head == BUFFER_SIZE) {
             shm -> head = 0;
    	}
         }	
         if (sem_post(&shm -> mutex) == -1) {
            perror("sem_post");
    	exit(EXIT_FAILURE);
         }
         for(int i = 0; i < n; ++i) {
           if (sem_post(&shm -> quantite) == -1) {
    	    perror("sem_wait");
    	    exit(EXIT_FAILURE);
           }  
        }	
        shm -> n = n;
     }
     buff[0] = '\0';
    }
    conso :

    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
    void consum(shared_mem *shm) {
      int quantite; 
      sem_getvalue(&shm -> quantite, &quantite);
      if(quantite > 0) {
         if(sem_wait(&shm -> mutex) == -1) { 
    	perror("sem_wait");
    	exit(EXIT_FAILURE);
         }
         for(int i = 0; i < shm -> n; ++i) {
           errno = 0;
           char c = shm -> buffer[shm -> queue];
           if(write(STDOUT_FILENO, &c, 1) == -1 ) {
    	 if(errno != 0) {
    	     perror("write");
    	     exit(EXIT_FAILURE);
            } else {
                fprintf(stderr, "write:  can not write requested data\n");
                exit(EXIT_FAILURE);
    	}
         }
         shm -> queue += 1;
         if(shm -> queue == BUFFER_SIZE) {
           shm -> queue = 0;
         } 
       }   
       if (sem_post(&shm -> mutex) == -1) {
         perror("sem_post");
         exit(EXIT_FAILURE);
       }
       for(int i = 0; i <= shm -> n; ++i) { 
         if(sem_wait(&shm -> quantite) == -1) {
           perror("sem_wait");
           exit(EXIT_FAILURE);
         } 
       }  
     }
     
    }

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Citation Envoyé par poower Voir le message
    Dans ton algo il faudrait un autre sémaphore mutex initialisé à 0 pour contrôler l'accès au shm non ?
    Non, pas du tout : le sémaphore ne contrôle plus l'accès à la SHM, mais l'accès à une case précise pour le producteur et pour le consommateur.
    Il faut voir la SHM comme une liste circulaire, un serpent qui tourne sans fin. Le producteur ajoute à la tête du serpent tandis que le consommateur retire à la queue du serpent. Le sémaphore empêche le consommateur de dépasser le producteur.

    Le consommateur boucle à l'infini sur sem_wait. L'appel est bloquant tant que la valeur du sémaphore est à zéro. Dès que l'appel se débloque, il va lire la case d'indice i_c puis incrémente i_c.

    Le producteur utilise sem_getvalue. Si la valeur vaut N, alors il attend car la file est pleine. A toi de voir selon ton besoin. Fait-il une pause de X secondes ? Ou choisis-tu d'ajouter un second sémaphore pour compter non pas les cases utilisées mais les cases vides ? A toi de voir. Pour la pause, "sleep X", pour le nouveau sémaphore, c'est le consommateur qui fait un sem_post(S2) après avoir lu une case et le producteur qui fait un sem_wait(S2) en attente d'une case libre.
    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
     
    init: 2 sémaphores :
    sem_vide = N
    sem_plein = 0
    dans la SHM : i_c=0, i_p=0
     
    producteur :
     
    while( 1 )
    {
    	sem_wait(sem_vide)
    	ecrire dans la case i_p
    	++i_p; si i_p >= N alors i_p=0
    	sem_post(sem_plein)
    }
     
    consommateur :
     
    while( 1 )
    {
    	sem_wait(sem_plein)
    	lire la case i_c
    	++i_c; si i_c >= N alors i_c=0
    	sem_post(sem_vide)
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  5. #5
    Membre averti
    Homme Profil pro
    fdf
    Inscrit en
    Novembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : fdf

    Informations forums :
    Inscription : Novembre 2014
    Messages : 20
    Par défaut
    Ça marche mais pour afficher tous les messages je dois faire attendre le consommateur sleep(1) en entrant dans la boucle while(1) sinon il affiche que le premier et se bloque au niveau de sem_wait(full).
    Après avoir lu le premier message de taille n = 91 au retour de boucle pour le prochain message à lire n vaut toujours 91 et il ne passe pas l'instruction sem_wait(full) .

    Dans les règles de synchronisation des processus on ne doit pas faire de supposition quant à la vitesse ou au nombre de processus, est-ce que sa signifie en partie qu'on a pas le droit d'utiliser sleep(X) ou ça signifie autre chose ?

  6. #6
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Je t'ai donné une possibilité d'algorithme sans "sleep X". Je trouve toujours plus "propre" de ne pas utiliser "sleep" pour la synchronisation, mais à toi de voir selon tes besoins. Ce serait mieux de gérer avec un sémaphore comme expliqué.

    Par contre, l'algorithme que je t'ai donné ne fonctionne qu'avec un seul producteur et un seul consommateur. Il n'est pas trop difficile à adapter pour plusieurs producteurs et plusieurs consommateurs.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

Discussions similaires

  1. Multithread producteurs consommateurs
    Par barney2008 dans le forum Linux
    Réponses: 3
    Dernier message: 27/04/2008, 16h31
  2. Sémaphores Producteur consommateur Windows
    Par Artusamak dans le forum Windows
    Réponses: 4
    Dernier message: 06/04/2007, 09h40
  3. Interface producteur/consommateur utilisant SWING
    Par El pistol dans le forum AWT/Swing
    Réponses: 17
    Dernier message: 03/04/2006, 15h06
  4. [Threads]Producteur - Consommateur - Filemessages
    Par slim dans le forum Concurrence et multi-thread
    Réponses: 10
    Dernier message: 08/03/2006, 18h57
  5. Réponses: 8
    Dernier message: 09/02/2006, 18h51

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