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);
}