Bonsoir à tous,

Après un premier épisode palpitant, revoici Vrashnak et ses programmes qui passent la compilation mais qui foirent magistralement à l'exécution.
Je m'explique : ce programme est censé simuler une caisse de supermarché et utilise des threads pour calculer une moyenne arithmétique, une moyenne quadratique et une somme des cubes des éléments d'un tableau d'entiers.
A l'éxécution, une erreur de segmentation mémoire apparaît après que les "clients" aient finis leurs "achats" (les tableaux sont remplis, et on va lancer les threads).

Ci-dessous le code du programme (très long, je m'en excuse)

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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <pthread.h>
#define MAXP 50
#define MAXC 5000
#define PRIXMAX 99
struct Cli
{
int id;
int *chariot;
};
 
typedef struct Cli Client;
/*Ls trois fonctions suivantes permettent de simuler le comportement de la caissière
Les fonctions sont adaptées à l'utilisation par un thread de type pthread_t*/
void* Moyenne (void* pdata)
{
	double* somme=malloc(sizeof(double));
	*somme=0;
	int* moyenne=(int*)pdata;
	for (int i=0; i<MAXP; i++)
	{
		*somme+=(double)*(moyenne+i);
	}
	*somme/=MAXP;
	return (void*) somme;
}
 
void* Quadratique(void* pdata)
{
	double* somme=malloc(sizeof(double));
	*somme=0;
	int* moyenne=(int*)pdata;
	for (int i=0; i<MAXP; i++)
	{
		*somme+=(double)((*(moyenne+i))*(*(moyenne+i)));
	}
	*somme/=MAXP;
	*somme=sqrt(*somme);
	return (void*) somme;
}
 
void* Cube(void* pdata)
{
	double* somme=malloc(sizeof(double));
	*somme=0;
	int* moyenne=(int*)pdata;
	for (int i=0; i<MAXP; i++)
	{
		*somme+=(double)((*(moyenne+i))*(*(moyenne+i))*(*(moyenne+i)));
	}
	return (void*) somme;
}
int main()
{
	int prix, i;
	Client *p=malloc(MAXC*sizeof(struct Cli));
	srand(time(NULL));
	pthread_t moy, qua, cub;
	//void* 
	void** un;
	void** deux;
	void** trois;
	double* val;
	double histo[MAXC][3];
	printf("Ouverture du magasin.\n");
	//Initialisation des clients
	for(i=0;i<MAXC;i++)
	{
		Client *Cl=p+i;
		Cl->id=i;
		Cl->chariot=malloc(MAXP*sizeof(int));
	}
	printf("Les clients entrent dans le magasin.\n");
	//Les clients rentrent tous dans le magasin (pas de valeur max de clients en même temps)
	for(i=0;i<MAXC;i++)
	{
		for(int j=0;j<MAXP;j++)
		{
			p[i].chariot[j]=(rand()%PRIXMAX)+1;
		}
	}
	printf("Les clients passent à la caisse.\n");
	//Calcul multithreadé du ticket de chaque client
	for(i=0;i<MAXC;i++)
	{
		Client tmp;
		tmp=*(p+i);
		(void*)tmp.chariot;
		//on lance les trois threads de façon quasi-simultanée
		pthread_create(&moy,NULL,Moyenne,tmp.chariot);
		pthread_create(&qua,NULL,Quadratique,tmp.chariot);
		pthread_create(&cub,NULL,Cube,tmp.chariot);
		//récupération de la valeur renvoyée par le premier thread
		pthread_join(moy,un);
		val=(double*)*un;
		histo[i][0]=(double)*val;
		//récupération du second thread
		pthread_join(qua,deux);
		val=(double*)*deux;
		histo[i][1]=(double)*val;
		//récupération du troisième thread
		pthread_join(cub,trois);
		val=(double*)*trois;
		histo[i][2]=(double)*val;
		free(un);
		free(deux);
		free(trois);
		free(val);
	}
	printf("Les clients sortent du magasin.\n");
	//Libération de la mémoire allouée à chaque client
	for(i=0;i<MAXC;i++) 
	{
    	free(p[i].chariot);
	}
	free(p);
	printf("Fermeture du magasin.\n");
	//Affichage de tous les tickets des clients
	for(i=0;i<MAXC;i++)
	{
		printf("Ticket du client %d : %0.4f %0.4f %0.4f \n",i,histo[i][0],histo[i][1],histo[i][2]);
	}
}
Et le résultat à l'exécution :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
[vrashnak@Reghar Theorie_Systeme_Exploitation]$ time ./thr
Ouverture du magasin.
Les clients entrent dans le magasin.
Les clients passent à la caisse.
Erreur de segmentation (core dumped)
 
real	0m0.335s
user	0m0.013s
sys	0m0.041s
D'après ce que je vois, le problème vient clairement de la partie de code constituée par la boucle utilisant les threads. J'en ai donc déduit que mes pointeurs de threads étaient à refaire, mais j'ai beau chercher, je ne vois pas comment corriger le bousin, chaque correction me créant une erreur de compilation.

Avez-vous une idée ?

Cordialement,

Vrashnak