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 :

les thread et mutex et cond


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Août 2008
    Messages : 35
    Par défaut les thread et mutex et cond
    Bpnjour à tous,

    J'ai posté ce message sur un autre site mais je n'arrive pas à avoir certaines précisions sur les thread.

    j'ai trouvé ce code et j'essaie de le comprendre

    voici le code

    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
     
    #include <windows.h>
    #define psleep(sec) Sleep((sec)*1000)
     
    #if defined(Win32)
      #include <windows.h>
      #define psleep(sec) Sleep((sec)*1000)
    #elif defined(Linux)
      #include <unistd.h>
      #define psleep(sec)sleep((sec))
    #endif
     
    #define STOCK_INITIAL 20
    #define NOMBRE_CLIENT 5
     
     
    /* http://franckh.developpez.com/tutoriels/posix/pthreads/ */
     
     
    /* Structure stockant les informations des threads clients et du magasin */
    typedef struct S_Magasin S_Magasin;
     
    struct S_Magasin
    {
      int S_Magasin_Fin[NOMBRE_CLIENT];
      int S_Magasin_Stock;
     
      pthread_t S_Magasin_Thread_Magasin;
      pthread_t S_Magasin_Thread_Client[NOMBRE_CLIENT];
     
      pthread_mutex_t S_Magasin_Mutex_S_Magasin_Stock;
      pthread_cond_t S_Magasin_Condition_S_Magasin_Stock;
      pthread_cond_t S_Magasin_Condition_Client;
    };
     
    static S_Magasin s_magasin=
    {
      .S_Magasin_Fin=0,
      .S_Magasin_Stock=STOCK_INITIAL,
      .S_Magasin_Mutex_S_Magasin_Stock=PTHREAD_MUTEX_INITIALIZER,
      .S_Magasin_Condition_S_Magasin_Stock=PTHREAD_COND_INITIALIZER,
      .S_Magasin_Condition_Client=PTHREAD_COND_INITIALIZER,
    };
     
     
    /* Fonction pour tirer un nombre au sort entre 0 et nombre_maximum */
    static int fonction_generer_nombre_aleatoire(int nombre_maximum)
    {
       double nombre_aleatoire;
     
       nombre_aleatoire=(double)nombre_maximum*rand();
       nombre_aleatoire= nombre_aleatoire/(RAND_MAX+1.0);
     
       return((int)nombre_aleatoire);
    }
     
     
    /* Fonction pour le thread du magasin */
     
    /* Le thread attendant que la condition soit remplie pour s'activer, nous n'avons plus besoin du test
       à l'intérieur de la boucle, nous pouvons donc directement remplir le stock. Nous pouvons voir un processus
       particulier en ce qui concerne les conditions. En effet, si on regarde le début du corps de la boucle,
       on peut s'apercevoir que le thread prend le mutex et se met en attente de la condition. En réalité,
       le thread relâche le mutex aussitôt et le reprend automatiquement lorsque la condition est vraie
       et qu'il soit réveillé par un autre thread. Lorsque la stock est remplit, la fonction le signale au thread
       du client courant. */
     
    static void* fonction_magasin(void *p_donnee)
    {
      while(1)
      {
        /* Debut de la zone protegee */
        pthread_mutex_lock(&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);
        pthread_cond_wait(&s_magasin.S_Magasin_Condition_S_Magasin_Stock,&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);
     
        s_magasin.S_Magasin_Stock=STOCK_INITIAL;
        printf("Remplissage du stock du magasin de %d articles !\n",s_magasin.S_Magasin_Stock);
     
        pthread_cond_signal(&s_magasin.S_Magasin_Condition_Client);
        pthread_mutex_unlock(&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);
        /* Fin de la zone protegee. */
      }
     
      return NULL;
    }
     
     
    /* Fonction pour les threads des clients */
     
    /* Cette fonction a aussi eu droit à un petit lifting. En effet, un test a été rajouté qui permet
       de déterminer si le stock est en quantité suffisante par rapport à la demande du client.
       Si ce n'est pas le cas, le thread le signal au thread du magasin qui prend le relais,
       le thread appelant ce met en attente le temps que le magasin réalise sa tâche. */
     
    static void* fonction_client(void *p_donnee)
    {
      int client_nombre_pris_sur_stock=0;
      int client_numero=(int)p_donnee;
     
      while(s_magasin.S_Magasin_Fin[client_numero]<3)
      {
        client_nombre_pris_sur_stock=fonction_generer_nombre_aleatoire(5);
     
        psleep(fonction_generer_nombre_aleatoire(2));
     
        /* Debut de la zone protegee */
        pthread_mutex_lock(&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);
     
        if(client_nombre_pris_sur_stock>s_magasin.S_Magasin_Stock)
        {
          pthread_cond_signal(&s_magasin.S_Magasin_Condition_S_Magasin_Stock);
          pthread_cond_wait(&s_magasin.S_Magasin_Condition_Client,&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);
     
          s_magasin.S_Magasin_Fin[client_numero]++;
        }
        else
        {
          s_magasin.S_Magasin_Stock-=client_nombre_pris_sur_stock;
     
          printf("Le client => %d, prend %d du stock,reste %d en stock !\n",client_numero,client_nombre_pris_sur_stock,s_magasin.S_Magasin_Stock);
        }
     
        pthread_mutex_unlock(&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);
        /* Fin de la zone protegee */
      }
     
      return NULL;
    }
     
     
    int main(int argc,char *argv[])
    {
      int i=0;
      int thread_magasin_retour=0;
      int thread_client_retour=0;
      void** pp_thread_magasin_join=NULL;
     
      /* Creation des threads. */
      printf("Creation du thread du magasin !\n");
      thread_magasin_retour=pthread_create(&s_magasin.S_Magasin_Thread_Magasin,NULL,fonction_magasin,NULL);
     
      /* Creation des threads des clients si celui du magasinn a reussi. */
      if(!thread_magasin_retour)
      {
        printf("Creation des threads clients !\n");
     
        for(i=0;i<NOMBRE_CLIENT;i++)
        {
          thread_client_retour=pthread_create(&s_magasin.S_Magasin_Thread_Client[i],NULL,fonction_client,(void*)i);
     
          if(thread_client_retour)
          {
            fprintf(stderr,"%s",strerror(thread_client_retour));
          }
        }
      }
      else
      {
        fprintf(stderr,"%s",strerror(thread_magasin_retour));
      }
     
      /* Attente de la fin des threads. */
     
      for(i=0;i<NOMBRE_CLIENT;i++)
      {
        pthread_join(s_magasin.S_Magasin_Thread_Client[i],NULL);
      }
     
      pthread_join(s_magasin.S_Magasin_Thread_Magasin,pp_thread_magasin_join);
     
      pthread_exit(pp_thread_magasin_join);
     
      return EXIT_SUCCESS;
    }
    j'aimerais savoir si mon raisonnement suivant et bon

    dans main je crée le thread magasin, il est initialisé à PTHREAD_MUTEX_FAST_NP
    j'appelle la fonction qui lui est associé

    la je mets un mutex sur la variable du stock du magasin

    pthread_mutex_lock(&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);

    , puisqu'elle n'est pas verouillé, elle est verouillé par le thread appelant qui est le thread magasin
    puis arrive le cond_wait, qui dévérouille le mutex, là, le thread magasin, attend le signal envoyé par les thread clients, pour que la condition

    &s_magasin.S_Magasin_Condition_S_Magasin_Stock

    , qu'attend le thread magasin soit signalé pr un des thread clients.

    à peu près en même temps, les thread clients sont crées un à un, ils sont initialisés à PTHREAD_MUTEX_FAST_NP, leur identifiant,respectif, est mis dans la variable
    S_Magasin_Thread_Client[NOMBRE_CLIENT];

    chaque thread client, mets un mutex sur

    pthread_mutex_lock(&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);

    là je teste si il reste assez de stock pour satisfaire le client,

    si oui
    j'enlève du stock ce qui est pris par ce client
    et je dévérouille
    pthread_mutex_unlock(&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);

    et je continue jusqu'à ce que le stock ne soit pas suffisant pour satisfaire un des clients

    et là j'ai

    si oui

    j'envoie le signal au thread magasin, pour lui dire ta condition est remplie
    pthread_cond_signal(&s_magasin.S_Magasin_Condition_S_Magasin_Stock);

    puis le thread client se met en attente du signal par le thread magasin que le stock a été refait
    et dévérouille &s_magasin.S_Magasin_Mutex_S_Magasin_Stock
    pthread_cond_wait(&s_magasin.S_Magasin_Condition_Client,&s_magasin.S_Magasin_Mutex_S_Magasin_Stock);

    je reprends mon thread magasin
    &s_magasin.S_Magasin_Mutex_S_Magasin_Stock est donc dévérouillé, donc le thread magasin
    remplie le stock

    puis le thread magasin dit au thread client que la condition est remplie
    et il dévérouille

    &s_magasin.S_Magasin_Mutex_S_Magasin_Stock
    mis par lui même

    et se revérouille
    &s_magasin.S_Magasin_Mutex_S_Magasin_Stock

    et se met en attente à nouveau

    je reprends le thread client
    il dévérouille

    &s_magasin.S_Magasin_Mutex_S_Magasin_Stock
    mis par lui même

    et recommence à enlever du stock par les clients

    maintenant j'aimerais faire une action par exemple pour 3 remplissages de stock on arrête tout
    et là, je rame, je n'arrive plus à comprendre comment faire avec les 2 attentes réciproques des thread, et leur signal que chacun, thread magasin et les thread clients, s'envoient les uns à l'autre

    c'est là que j'ai du mal avec la pratique pour savoir qui commande l'autre,

    faut il faire un

    pthread_cancel(pthread_t thread);

    et où

    dans le thread magasin sur tous les thread clients ou
    dans le thread client pour chaque client sur le thread magasin

    merci d'avance

  2. #2
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Août 2008
    Messages : 35
    Par défaut
    bonsoir,

    est ce que quelqu'un pourrait m'aider pour la compréhension des threads

    merci d'avance.

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par quark22 Voir le message
    est ce que quelqu'un pourrait m'aider pour la compréhension des threads
    Un peu de lecture pour s'éclaircir les idées ? http://perso.numericable.fr/~pdeiber...ssus-leger.pdf
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Août 2008
    Messages : 35
    Par défaut
    merci ram_0000,

    j'ai lu le fichier que tu m'as conseillé,plutôt difficile, mais certainement essentiel.

    disons que le fichier, en question, apprend le fonctionnement de l'ordinateur, ou plutôt, le partage des ressources (cpu , mémoire) entre les processus légers, ou les processus lourds, mais pas le fonctionnement des cond ou signal des threads, pas la gestion des threads.

    quelqu'un pourrait t-il me dire si mon raisonnement de mon premier post est bon ou non ?

    merci d'avance...

    tous les conseils sont bienvenus, merci

    depuis le message, j'ai résolu en partie le problème, mais j'ai du mal, à gérer
    les threads, vraiment bien, j'aimerais faire un tchat multi utilisateur, j'ai fait un petit code, avec les sockets, du type "SOCK_STREAM".

    mais je n'ai réussi à faire qu'un petit message envoyé par le serveur à 1 client, et au client d'envoyer un petit message au serveur.

    j'aimerais faire, avec les threads, la gestion d'une discussion, entre plusieurs utilisateurs.

    il y a t-il des livres en français, pour créer un tchat multi-utilisateur

Discussions similaires

  1. Gérer les threads / Mutex
    Par Invité dans le forum Threads & Processus
    Réponses: 13
    Dernier message: 05/06/2013, 13h03
  2. Les Threads... J'en remet une couche :)
    Par Higestromm dans le forum C++
    Réponses: 5
    Dernier message: 17/11/2004, 12h19
  3. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 17h25
  4. Question simple sur les threads :)
    Par momox dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/06/2003, 04h13
  5. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59

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