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
| #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>
#define MAXP 50
#define MAXC 150
#define NBCLI 100
#define PRIXMAX 99
int caisse[4];//nombre de clients attendant à chaque caisse
sem_t sem_portique, sem_acces_caisse, sem_caisse[4];//sémaphores utilisés dans la programmation
float histo[MAXC][3];
struct Cli
{
int id;
int chariot[MAXP];
};
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;
}
/*La procédure client utilisant les sémaphores. La fonction est utilisée par un thread.*/
void* Client_sim(void* pdata)
{
int i, idc=(int) pdata;
Client C;
C.id=idc;
sem_wait(&sem_portique);//Entrée du client dans le magasin si possible
printf("Entree du client %d \n",C.id);
for(i=0;i<MAXP;i++)
{
C.chariot[i]=(int)(1+rand())%(50);//remplissage du chariot du client
}
printf("Fin des achats pour le client %d \n",C.id);
sem_wait(&sem_acces_caisse);//Demande du client pour un accès au tableau des files des caisses
i=find_caisse_minimale();//Recherche et sauvegarde de la caisse la moins remplie
sem_post(&sem_acces_caisse);
sem_wait(&sem_caisse[i]);//attente à la caisse ayant la plus petite file d'attente
caisse_client(C.chariot, i, C.id);
sem_post(&sem_caisse[i]);
printf("Temps passe dans le magasin pour le client %d : temps \n",C.id);
sem_post(&sem_portique);//Sortie du client
}
//Cette fonction est la seule utilisant un if. Elle retourne le numéro de la caisse ayant le plus petit nombre de
//clients qui y attendent. Si deux caisses ont le même nombre de clients y attendant, c'est la première qui est renvoyée.
int find_caisse_minimale()
{
int i,min=0;
for(i=1;i<4;i++)
{
if(caisse[min]<caisse[i])
{
min=caisse[i];
}
}
caisse[min]--;
return min;
}
//Cette procédure calcule le ticket d'un client et décrémente le sémaphore associé une fois le travail effectué.
//Elle utilise la même structure que la caisse threadée du deuxième programme séquentiel.
void caisse_client(int chariot[], int i, int id)
{
pthread_t moy, qua, cub;
void* un;
void* deux;
void* trois;
double* val;
pthread_create(&moy,NULL,Moyenne,chariot);
pthread_create(&qua,NULL,Quadratique,chariot);
pthread_create(&cub,NULL,Cube,chariot);
pthread_join(moy,&un);
pthread_join(qua,&deux);
pthread_join(cub,&trois);
val=(double*)un;
histo[id][0]=(double)*val;
val=(double*)deux;
histo[id][1]=(double)*val;
val=(double*)trois;
histo[id][2]=(double)*val;
free(un);
free(deux);
free(trois);
sem_wait(&sem_acces_caisse);
caisse[i]++;
sem_post(&sem_acces_caisse);
}
int main()
{
int i;
void* useless;
caisse[0]=MAXC/4;caisse[1]=MAXC/4;caisse[2]=MAXC/4;caisse[3]=MAXC/4;
pthread_t clients[MAXC];
srand(time(NULL));
sem_init(&sem_portique,0,NBCLI);
sem_init(&sem_acces_caisse,0,1);
for(i=0;i<4;i++)
{
sem_init(&sem_caisse[i],0,caisse[i]);
}
for(i=0;i<MAXC;i++)
{
pthread_create(&clients[i],NULL,Client_sim,i);
}
for(i=0;i<MAXC;i++)
{
pthread_join(useless,&clients[i]);
}
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]);
}
return 0;
} |