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 :

Threads pas vraiment threadé.


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    77
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 77
    Points : 58
    Points
    58
    Par défaut Threads pas vraiment threadé.
    Salut à tous
    Je suis toujours dans mes threads et je cale toujours... j'ai récupéré plein d'exemples et tutoriels, mais dès que j'essaie de l'appliquer à mon pgm ça merde...

    J'ai un programme tout con :
    Un thread mère qui lit un fichier et donne les commandes à exécuter au fur et à mesure que les threads les demandent.
    4 threads fils qui exécutent les commandes que le thread mère leur passe.

    Or voici ce que ça me donne à l'écran :

    Fin lecture
    16h 25min 27sec - Thread : 1
    16h 25min 27sec - thread 1 demande commande
    16h 25min 27sec - Thread : 3
    16h 25min 27sec - Thread : 2
    Mise a dispo de la commande1
    16h 25min 27sec - Thread : 4
    16h 25min 27sec - Execution de la commande1 par thread 3
    Attente pour thread 3 de 20 secondes
    16h 25min 27sec - thread 2 demande commande
    16h 25min 27sec - Execution de la par thread 1
    Attente pour thread 1 de 10 secondes
    16h 25min 27sec - thread 4 demande commande
    Mise a dispo de la commande2
    16h 25min 27sec - Execution de la commande2 par thread 2
    Attente pour thread 2 de 5 secondes
    16h 25min 32sec - Fin attente pour thread 2
    16h 25min 32sec - thread 2 demande commande
    Mise a dispo de la commande3
    16h 25min 32sec - Execution de la commande3 par thread 4
    Attente pour thread 4 de 60 secondes
    16h 25min 37sec - Fin attente pour thread 1
    16h 25min 37sec - thread 1 demande commande
    Mise a dispo de la commande4
    16h 25min 37sec - Execution de la commande4 par thread 2
    Attente pour thread 2 de 5 secondes
    16h 25min 42sec - Fin attente pour thread 2
    16h 25min 42sec - thread 2 demande commande
    Mise a dispo de la commande5
    16h 25min 42sec - Execution de la commande5 par thread 1
    Attente pour thread 1 de 10 secondes

    Je n'arrive pas à comprendre pourquoi le thread mère ne donne pas les commandes à exécuter lorsque les threads en demande, mais attend que le thread en cours se termine pour "libérer" une commande.

    Je vous mets le code si toutefois vous voyez mon erreur...

    Merci d'avance

    Iza

    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
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
     
    #include<stdio.h>
    #include<pthread.h>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    #include <time.h>
     
    #define psleep(sec) Sleep ((sec) * 1000)
     
    struct MaillonToExecute
    {
    	struct MaillonToExecute *MaillonNext;
    	char Commande[80];
    };
     
    /* definition d'une structure convenable */ 
    typedef struct
    {
      char  *p_commande;					
      BOOL *p_KillAllThreads;
      pthread_mutex_t *p_commande_lock;		/* le verrou de la  variable s */
      pthread_cond_t *p_commande_cond;		
      pthread_cond_t *p_exec_cond;		
      int n;								/* le numero du thread */
    } DATA;
     
     
    /* Fonction pour le thread mere. */
    void *Fn_Getliste(void *Arg)
    {
    	DATA D = *(DATA *)Arg;
    	FILE *HandleRun;
    	char *FileName="FileCommand.txt";
    	char Line[80]=" ";
    	char *PtrString;
    	struct MaillonToExecute *ListeToExecute,*Maillon,*Ptr;
    	BOOL ReadOne=TRUE;
     
    	if(HandleRun=fopen(FileName,"rb"))
    	{	
    		while(fgets(Line,sizeof(Line),HandleRun))
    		{
    			if(Maillon=(struct MaillonToExecute *)calloc(1,sizeof(struct MaillonToExecute)))
    			{
    				sprintf(Maillon->Commande,"%s",Line);
    				if(PtrString=strchr(Maillon->Commande,'\n')) *PtrString='\0';
    				if(PtrString=strchr(Maillon->Commande,'\r')) *PtrString='\0';
    				Maillon->MaillonNext=NULL;
    				if(ReadOne)
    				{
    					ListeToExecute=Maillon;
    					ReadOne=FALSE;
    				}else
    				{
    					Ptr->MaillonNext=Maillon;
    				}
    				Ptr=Maillon;	
    			}
    		}
    		fclose(HandleRun);
    	}
     
    	printf("Fin lecture\n");
    	Maillon=ListeToExecute;
    	while(1)
    	{	
    	/* Debut de la zone protegee. */
    	pthread_mutex_lock(D.p_commande_lock);
    	pthread_cond_wait(D.p_commande_cond,D.p_commande_lock);
     
    	if(*D.p_KillAllThreads) 
    	{
    		printf("attente de DIE\n");
    		pthread_cond_broadcast(D.p_exec_cond);
    	}else
    	{
    		sprintf(D.p_commande,"%s",Maillon->Commande);
    		printf("Mise a dispo de la %s \n",D.p_commande);
     
    		Ptr=Maillon;
    		Maillon=Maillon->MaillonNext;
    		free(Ptr);
     
    		if(!Maillon) *D.p_KillAllThreads=TRUE;
    		pthread_cond_signal(D.p_exec_cond);
     
    	}
    	pthread_mutex_unlock (D.p_commande_lock);
    	/* Fin de la zone protegee. */
     
    	}
     
    	return NULL;
    }
     
    void *Fn_Threads(void *Arg)
    {
      DATA D = *(DATA *)Arg;
      int sec;
      time_t timestamp;
      struct tm *t;
      BOOL DieThread=FALSE;
     
     
      timestamp=time(NULL);
      t=localtime(&timestamp);
      sec=t->tm_sec;
     
      printf("%02uh %02umin %02usec - Thread : %ld \n",t->tm_hour,t->tm_min,t->tm_sec,D.n);
     
     
      while(!DieThread)
      {
    	  /* Debut de la zone protegee. */
    	  pthread_mutex_lock(D.p_commande_lock);
     
     
    	  if(!*D.p_commande)
    	  {
     
    		  pthread_cond_signal(D.p_commande_cond);
    		  timestamp=time(NULL);
    		  t=localtime(&timestamp);
     
    		  printf("%02uh %02umin %02usec - thread %ld demande commande\n",t->tm_hour,t->tm_min,t->tm_sec,D.n);
    		  pthread_cond_wait(D.p_exec_cond,D.p_commande_lock);
    		  if(*D.p_KillAllThreads==TRUE && !*D.p_commande) 
    		  {
    			  printf("Thread num %ld DIE\n",D.n);
    			  DieThread=TRUE;
    			  pthread_mutex_unlock(D.p_commande_lock);
    			  break;
    		  }
    	  }
    	  timestamp=time(NULL);
    	  t=localtime(&timestamp);
     
    	  printf("%02uh %02umin %02usec - Execution de la %s par thread %ld\n",t->tm_hour,t->tm_min,t->tm_sec,D.p_commande,D.n);
    	  strncpy(D.p_commande,"\0",1);
    	  pthread_mutex_unlock(D.p_commande_lock);
    	  /* Fin de la zone protegee. */
     
    	  if(D.n==1) sec=10;
      	  if(D.n==2) sec=5;
    	  if(D.n==3) sec=20;
    	  if(D.n==4) sec=60;
     
    	  printf("Attente pour thread %ld de %ld secondes\n",D.n,sec);
    	  psleep(sec); 
      	  timestamp=time(NULL);
    	  t=localtime(&timestamp);
     
    	  printf("%02uh %02umin %02usec - Fin attente pour thread %ld\n",t->tm_hour,t->tm_min,t->tm_sec,D.n);
      }
      printf("FIN %ld\n",D.n);
    	return NULL;
     
     
    }
     
     
    int main(int argc, char **argv)
    {
      pthread_t *ListeThread;    
      void *retval;
      int cpu, i;
      DATA *A;
      double s=0;     /* la variable partagee */ 
      pthread_mutex_t s_lock; 
      pthread_cond_t s_cond_commande,s_cond_exec;
      BOOL KillAllThreads=FALSE;
      char Commande[80]="";
     
      cpu = 5;
     
      A = (DATA *)calloc(cpu+1, sizeof(DATA));
     
      ListeThread = (pthread_t *) calloc(cpu, sizeof(pthread_t));
     
     /* initialisation de la variable correspondant aux verrous et signaux*/
      pthread_mutex_init(&s_lock,NULL);
      pthread_cond_init(&s_cond_commande,NULL);
      pthread_cond_init(&s_cond_exec,NULL);
     
      for(i=0;i<cpu;i++)
        {
     
          A[i].n=i;           
          A[i].p_commande_lock=&s_lock;
    	  A[i].p_exec_cond=&s_cond_exec;
    	  A[i].p_commande_cond=&s_cond_commande;
    	  A[i].p_KillAllThreads=&KillAllThreads;
    	  A[i].p_commande=Commande;
     
     
    	  if(i==0)
    	  {
    		if(pthread_create(&ListeThread[i],NULL,Fn_Getliste,&A[i]))
    		{
    			fprintf(stderr, "%s: creation du thread impossible\n", argv[0]);
    			return(1);
    		}
    		Sleep(5000);
     
    	  }else
    	  {	
    		if(pthread_create(&ListeThread[i],NULL,Fn_Threads,&A[i]))
    		{
    			fprintf(stderr, "%s: creation du thread impossible\n", argv[0]);
    			return(1);
            }
    	  }
        }
     
      for(i=1;i<cpu;i++)
        {
          if(pthread_join(ListeThread[i], &retval))
            {
              fprintf(stderr, "%s: synchronisation sur le thread impossible\n", argv[0]);
              return(1);
            }
     
        }
     
      pthread_cancel(ListeThread[0]);
     
      printf("s = %f\n", s);
      return(0);
    }

  2. #2
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    77
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 77
    Points : 58
    Points
    58
    Par défaut
    Je crois avoir trouvé mon erreur !

  3. #3
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Déjà, apprends à te servir de pthread_cond_wait : si pthread_cond_wait s'applique à un mutex, qui doit être pris, ce n'est pas pour faire joli : tu dois définir une condition sur l'état des variables protégées par le mutex, et vérifier cette condition dans une boucle.

    (Tu ne t'es pas demandé pourquoi verrouiller un mutex pour le passer aussitôt à pthread_cond_wait qui le déverrouille immédiatement?)

    Une "condition variable" n'est pas une variable booléenne que tu peux mettre à 1; en fait, ce n'est pas une variable du tout : c'est un outil de synchronisation des threads, qui tu dois utiliser correctement (comme n'importe quel livre, doc, tutoriel correct sur pthread le montrera).

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

Discussions similaires

  1. [WEBSERVICE+THREAD] Pas d'accès
    Par ghost942 dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 14/10/2008, 00h44
  2. [Tkinter] Thread pas logique!
    Par airod dans le forum Tkinter
    Réponses: 4
    Dernier message: 26/11/2006, 22h36
  3. threads pas Thread ! (1 tte tite question)
    Par lagra3 dans le forum Langage
    Réponses: 3
    Dernier message: 11/08/2006, 12h28
  4. [JPanel] un thread pas très catholique...
    Par calogerogigante dans le forum AWT/Swing
    Réponses: 25
    Dernier message: 21/05/2006, 22h01

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