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 :

Petit probleme de comprehension sur les threads


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 18
    Points : 18
    Points
    18
    Par défaut Petit probleme de comprehension sur les threads
    Bonsoir a tous. Ca fait pas longtemps que je me suis initié aux threads grace notamment au superbe tutos presents dans ce site. Cependant, il y a quelque chose que j'arrive pas a assimiler. Et je tiens beaucoup a avoir la réponse sur ce point.

    Je vais commencer par poster le code de la partie concernée. En fait, ça concerne les conditions. Je poste la fonction store et la fonction client :

    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
    static void * fn_store (void * p_data)
     
    {
       while (1)
       {
          /* Debut de la zone protegee. */
     
          pthread_mutex_lock (& store.mutex_stock);
          pthread_cond_wait (& store.cond_stock, & store.mutex_stock);
     
     
          store.stock = INITIAL_STOCK;
          printf ("Remplissage du stock de %d articles !\n", store.stock);
     
     
          pthread_cond_signal (& store.cond_clients);
          pthread_mutex_unlock (& store.mutex_stock);
          /* Fin de la zone protegee. */
     
       }
     
       return NULL;
    }
    Celle des clients :
    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
    static void * fn_clients (void * p_data)
    {
     
       int nb = (int) p_data;
     
       while (1)
       {
     
          int val = get_random (6);
     
     
          psleep (get_random (3));
     
          /* Debut de la zone protegee. */
     
          pthread_mutex_lock (& store.mutex_stock);
     
          if (val > store.stock)
          {
     
             pthread_cond_signal (& store.cond_stock);
             pthread_cond_wait (& store.cond_clients, & store.mutex_stock);
     
          }
     
          store.stock = store.stock - val;
          printf (
             "Client %d prend %d du stock, reste %d en stock !\n",
     
             nb, val, store.stock
          );
     
          pthread_mutex_unlock (& store.mutex_stock);
          /* Fin de la zone protegee. */
     
       }
     
       return NULL;
    }
    Lorsque le programme commence, on suppose que le thread de la fonction store est le premier a atteindre le mutex. Il le verrouille donc, et continue son parcours jusqu'à trouver la fonction pthread_cond_wait. Il block alors sur cette ligne, et libère le mutex. Ensuite l'un des thread des clients atteint a son tour le mutex, il le verrouille donc. Supposons que la quantité ne soit pas suffisante. Il entre alors dans le if et rencontre l'instruction pthread_cond_signal. Le thread de store se réveille alors et reverrouille le mutex.
    Mon problème c'est que comment ca se fait que le mutex soit reverouillé par le thread de store alors qu'il est deja verrouillé par le thread de la fonction du client?

    J'espère que vous avez compris. Si vous avez besoin d'explication n'hésitez pas. Merci d'avance.

  2. #2
    Nouveau membre du Club
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Points : 30
    Points
    30
    Par défaut
    Je ne suis pas un spécialiste des threads, j'ai essayé une fois mais ça ne m'a pas apporté grand chose...

    Je suppose que ton problème vient du fait que les boucles ne mettent pas le même temps a s'exécuter et que la boucle dans fn_store est plus rapide que l'autre, ce qui fait qu'elle verrouille plus rapidement le mutex que fn_clients.

    "comment ca se fait que le mutex soit reverouillé par le thread de store alors qu'il est deja verrouillé par le thread de la fonction du client?"

    Si ça se trouve la fonction client ne verrouille jamais le mutex. Faudrait vérifier le résultat renvoyer par pthread_mutex_lock pour en être sur.

  3. #3
    Membre à l'essai
    Inscrit en
    Juillet 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 18
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jackyzgood Voir le message
    Je ne suis pas un spécialiste des threads, j'ai essayé une fois mais ça ne m'a pas apporté grand chose...

    Je suppose que ton problème vient du fait que les boucles ne mettent pas le même temps a s'exécuter et que la boucle dans fn_store est plus rapide que l'autre, ce qui fait qu'elle verrouille plus rapidement le mutex que fn_clients.

    "comment ca se fait que le mutex soit reverouillé par le thread de store alors qu'il est deja verrouillé par le thread de la fonction du client?"

    Si ça se trouve la fonction client ne verrouille jamais le mutex. Faudrait vérifier le résultat renvoyer par pthread_mutex_lock pour en être sur.
    Toute d'abord merci pour ta réponse. En fait, le programme n'a pas de problèmes. Il marche parfaitement. Et justement ce qui me dérange c'est qu'il fonctionne! Car d'après les connaissances que j'ai acquis dans le cours en ce qui concerne les conditions et les mutexe, j'ai constaté que normalement il y aurait un problème dans le fonctionnement (Le problème est décrit au premier post). Donc j'aimerais qu'on corrige mon raisonnement ou tout simplement mes connaissances.

    Donc si quelqu'un pouvait me venir en aide. Je lui en serait reconnaissant

  4. #4
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut

    Mon problème c'est que comment ca se fait que le mutex soit reverouillé par le thread de store alors qu'il est deja verrouillé par le thread de la fonction du client?
    Lorsque que pthread_cond_wait reverrouille le mutex lors du reveille il fait l'équivalent d'un pthread_mutex_lock, si celui ci est déjà vérrouillé il devra attendre avant de pouvoir le prendre.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par tipeh Voir le message
    Toute d'abord merci pour ta réponse. En fait, le programme n'a pas de problèmes. Il marche parfaitement. Et justement ce qui me dérange c'est qu'il fonctionne! Car d'après les connaissances que j'ai acquis dans le cours en ce qui concerne les conditions et les mutexe, j'ai constaté que normalement il y aurait un problème dans le fonctionnement (Le problème est décrit au premier post). Donc j'aimerais qu'on corrige mon raisonnement ou tout simplement mes connaissances.

    Donc si quelqu'un pouvait me venir en aide. Je lui en serait reconnaissant
    votre confusion vient sans doute du double rôle que vous faites jouer à la "condition"…

    dans un schéma producteur/consommateur,
    le consommateur attend la condition "stock suffisant"
    le producteur attend la condition "stock critique" ou n'attend aucune condition s'il remplit le stock de manière discrète sur base d'un évènement extérieur (que vous simulez ici par le sleep…)

    ici vous faites attendre les 2 sur une condition "stock a changé"…

    (et si vous avez plusieurs clients, le fait de "signaler" que le "stock a changé" ne garantira pas que ce soit le thread "producteur" qui alimente le stock qui sera réveillé… pthread_cond_signal réveille 1 des threads qui attend pour la condition… n'importe lequel…)

  6. #6
    Membre à l'essai
    Inscrit en
    Juillet 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 18
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    Lorsque que pthread_cond_wait reverrouille le mutex lors du reveille il fait l'équivalent d'un pthread_mutex_lock, si celui ci est déjà vérrouillé il devra attendre avant de pouvoir le prendre.
    ahh d'accord je comprends beaucoup mieux. Merci beaucoup.

    Citation Envoyé par JeitEmgie
    votre confusion vient sans doute du double rôle que vous faites jouer à la "condition"…

    dans un schéma producteur/consommateur,
    le consommateur attend la condition "stock suffisant"
    le producteur attend la condition "stock critique" ou n'attend aucune condition s'il remplit le stock de manière discrète sur base d'un évènement extérieur (que vous simulez ici par le sleep…)

    ici vous faites attendre les 2 sur une condition "stock a changé"…

    (et si vous avez plusieurs clients, le fait de "signaler" que le "stock a changé" ne garantira pas que ce soit le thread "producteur" qui alimente le stock qui sera réveillé… pthread_cond_signal réveille 1 des threads qui attend pour la condition… n'importe lequel…)
    En fait, il y a deux conditions et non pas une : la première c'est la condition "Le stock n'est pas suffisant", la deuxieme "Le stock s'est fini de remplir".
    Donc les threads clients et magasins n'attendent pas la même condition.
    Celui du magasin attend que le stock ne soit pas suffisant (store.cond_stock), alors que les clients attendent que le magasin remplisse le stock (store.cond_clients).
    J'espere que j'ai bien compris ce que vous vouliez dire.


    S'il vous plait, encore deux petites question sur les threads pendant qu'on y est :
    1 - si on déverrouille un mutex déjà déverrouillé, il se passe quoi? (par exemple on enchaine deux pthread_mutex_unlock)
    2 - Est ce que le fait que deux thread au cours de leur programme utilisent simultanément la même fonction d'une même bibliothèque pose un problème? Ou est ce qu'il suffit juste que les deux fonctions n'utilisent pas une même variable statique.

  7. #7
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par tipeh Voir le message
    S'il vous plait, encore deux petites question sur les threads pendant qu'on y est :
    1 - si on déverrouille un mutex déjà déverrouillé, il se passe quoi? (par exemple on enchaine deux pthread_mutex_unlock)
    Cela va dépendre du type de mutex, en gros:
    • PTHREAD_MUTEX_NORMAL : comportement indéfini.
    • PTHREAD_MUTEX_ERRORCHECK : retourne un erreur.
    • PTHREAD_MUTEX_RECURSIVE : retourne une erreur.
    • PTHREAD_MUTEX_DEFAULT : comportement indéfini.



    2 - Est ce que le fait que deux thread au cours de leur programme utilisent simultanément la même fonction d'une même bibliothèque pose un problème? Ou est ce qu'il suffit juste que les deux fonctions n'utilisent pas une même variable statique.
    Tout dépend de la façon dont est faite ta fonction et de comment sont manipulée tes données.

    Par exemple si tes variables statique ne sont écrite que pendant la phase d'initialisation de ton appli, avant de lancer les threads, et que tu n'y accède qu'en lecture après, tu n'es pas obligé de les protéger.

    De même tes threads peuvent partager un pointeur sur une même structure qui ne sera pas statique et dans ce cas il faut protéger les accès a ta structure si jamais tu fais des lecture/écriture dessus.

    C'est a toi de savoir ce qui est partagé entre tes threads, comment, et pourquoi, et a partir de là tu décide s'il faut mettre une protection ou non.

    Pour résumer le C est l'un des langage qui te donne le plus de liberté d'action, cette liberté d'action implique d'être vigilent et de savoir ce que tu fais sans quoi tu le payera tôt ou tard.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  8. #8
    Membre à l'essai
    Inscrit en
    Juillet 2010
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 18
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    Cela va dépendre du type de mutex, en gros:
    • PTHREAD_MUTEX_NORMAL : comportement indéfini.
    • PTHREAD_MUTEX_ERRORCHECK : retourne un erreur.
    • PTHREAD_MUTEX_RECURSIVE : retourne une erreur.
    • PTHREAD_MUTEX_DEFAULT : comportement indéfini.





    Tout dépend de la façon dont est faite ta fonction et de comment sont manipulée tes données.

    Par exemple si tes variables statique ne sont écrite que pendant la phase d'initialisation de ton appli, avant de lancer les threads, et que tu n'y accède qu'en lecture après, tu n'es pas obligé de les protéger.

    De même tes threads peuvent partager un pointeur sur une même structure qui ne sera pas statique et dans ce cas il faut protéger les accès a ta structure si jamais tu fais des lecture/écriture dessus.

    C'est a toi de savoir ce qui est partagé entre tes threads, comment, et pourquoi, et a partir de là tu décide s'il faut mettre une protection ou non.

    Pour résumer le C est l'un des langage qui te donne le plus de liberté d'action, cette liberté d'action implique d'être vigilent et de savoir ce que tu fais sans quoi tu le payera tôt ou tard.
    D'accord. Un grand merci ça m'a beaucoup aidé

  9. #9
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par tipeh Voir le message
    En fait, il y a deux conditions et non pas une : la première c'est la condition "Le stock n'est pas suffisant", la deuxieme "Le stock s'est fini de remplir".
    juste, j'ai lu trop vite et passé sur la différence de noms des variables…

    mais restez vigilant quand même à la remarque sur "pthread_cond_signal"…
    si un jour vous devez ajouter une condition générale d'arrêt pour sortir de vos "while (1)",
    si vous ne broadcastez pas (pthread_cond_broadcast) le signal qui est dans le "while(1)" en sortie de celui-ci, alors les threads de l'autre type resteront bloqués dans leur "pthread_cond_wait" de leur propre boucle "while"…
    (et si vous utilisez pthread_cond_signal, seul 1 sera réveillé…)

    donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    while(1) {
        …
        pthread_cond_wait condition_A
        …
        if (condition_stop) break ;
        …
        pthread_cond_signal condition_B
        …
    }
     
    // pour être certains que TOUS les threads attendant condition_B aient une chance de découvrir à leur tour que condition_stop est maintenant vrai, sinon ils vont attendre pour toujours…
    pthread_cond_broadcast condition_B
    et récip. pour les threads attendant condition_B et signalant condition_A


    pour votre point 2:

    dans le cas des fonctions de la librairie C, leur compatibilité individuelle pour un usage multi-thread fait partie de leur documentation…

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Quelques questions sur les threads
    Par benj63 dans le forum C++Builder
    Réponses: 28
    Dernier message: 21/11/2005, 13h27
  2. Question sur les threads
    Par Linio dans le forum Concurrence et multi-thread
    Réponses: 10
    Dernier message: 21/10/2005, 09h08
  3. Question sur les threads
    Par nicolas66 dans le forum MFC
    Réponses: 4
    Dernier message: 03/06/2005, 20h57
  4. Aide sur les Threads
    Par themoye dans le forum MFC
    Réponses: 24
    Dernier message: 06/03/2005, 15h02
  5. Question simple sur les threads :)
    Par momox dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/06/2003, 04h13

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