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 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
| #include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/wait.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <signal.h>
#include <string.h>
#include <sys/file.h>
void pere1();
void pere2();
void fils1();
void fils2();
int verif();
int rand_a_b();
//variables des tubes en lecture et en ecriture - 1 pour chaque equipe
int pip1[2], pip2[2];
char buff[4];
// variables pour la sélection aléatoire des fichiers :
int num_fichier=0;
int min = 0000;
int max = 9999;
FILE *f= NULL;
int main()
{
// les processus (pg1 sous processus pa1.1 a 5 et processus pg2 avec sous processus pa2.1 a 5)
pid_t pg1,pg2;
// variables pour récupérer nb de points
int total_equipe1=0;
int total_equipe2=0;
// creation du premier processus general - equipe 1
pg1=fork();
if (pg1==0) {
// creation pipe a partager entre pg1 et ses 5 sous processus
// signale erreur si pb à la création d'un pipe
if(pipe(pip1) == -1)
{
perror("Erreur à la création du tube de communication 1." );
exit(-1);
}
// création des 5 sous processus - equipe 1
// et appelle les fonctions selon type de processus
int nb = 0;
pid_t pid;
do
{
pid = fork ();
if(pid==0){
fils1();}
nb++;
} while (nb < 5);
pere1();
// compteur de points equipe 1
// statut : exit(0) => 0 en cas de mort ou d'échec, exit(1) => 1 en cas de reussite
int tot1;
while(wait(&tot1) != -1){
total_equipe1 += WEXITSTATUS(tot1);
}
}
//creation du deuxième processus general - equipe 2
pg2=fork();
if (pg2==0) {
// creation pipe a partager entre pg2 et ses 5 sous processus
// signale erreur si pb à la création d'un pipe
if(pipe(pip2) == -1)
{
perror("Erreur à la création du tube de communication 2." );
exit(-1);
}
// création des 5 sous processus - equipe 2
// et appelle les fonctions selon type de processus
int nb = 0;
pid_t pid;
do
{
pid = fork ();
if(pid==0){
fils2();}
nb++;
} while (nb < 5);
pere2();
// compteur de points equipe 2
// statut : exit(0) => 0 en cas de mort ou d'échec, exit(res) => valeur de 'res' en cas de reussite
int tot2;
while(wait(&tot2) != -1){
total_equipe2 += WEXITSTATUS(tot2);
}
}
// qui a gagné ?
if (total_equipe1 > total_equipe2)
{
printf("l'equipe 1 gagne avec %d points contre %d points pour l'équipe 2", total_equipe1, total_equipe2);
}
else {
if (total_equipe1 < total_equipe2)
{
printf("l'equipe 2 gagne avec %d points contre %d points pour l'équipe 1", total_equipe2, total_equipe1);
}
else {
printf("les deux équipes dont à égalité avec %d points", total_equipe2);
}
}
return (0);
}// fin main
// equipe 1
void pere1(){
// mise en place du timing
alarm(20);
while(1) {
// sélection des fichiers
rand_a_b(min, max);
// ecriture et transmission des n° de fichiers via un pipe
close(pip1[0]);
printf("[Père :]Ecriture dans le tube de communication 1.\n" );
write(pip1[1], &num_fichier, sizeof(int));
//EOF est envoyé aux processus lisant les données écrites dans le tube
close(pip1[1]);
}
}
void fils1(){
// initialisation de la variable permettant d'incrémenter le compteur avec le nombre de points gagnés
int res = 0;
// initialisation de la variable signal
int sig =0;
// a répéter tant que le pipe n'est pas vide et tant que la sortie n'est pas explicitement demandée
do {
// verifie si il a recut un signal SIG_QUIT
signal(SIGQUIT, verif);
if (sig==1) exit(0);
//lit le n° de fichier
close(pip1[1]);
printf("[Fils :]Attente de lecture\n" );
read(pip1[0], buff, 4);
printf("[Fils :]Contenu de la lecture : %s\n",buff);
close(pip1[0]);
// transforme le int num_fichier en string et crée le nom de fichier
char s[10];
sprintf(s,"F%d.bin",buff);
// ouverture du ficher en lecture / ecriture binaire / à la fin
f= fopen(s,ab+);
// verrou exclusif et non bloquant sur le fichier
int l;
l = flock(f, LOCK_EX | LOCK_NB);
//si l=-1 alors, le fichier est deja utilisé, mise en attente et nouvelle tentative :
if (l==-1) {
do {
sleep(5);
l = flock(f, LOCK_EX | LOCK_NB);} while (l==-1);
// pid et ppid :
pid_t a = getpid();
pid_t b = getppid();
int c;
int p;
// ecriture du n° d'équipe (ppid) et du pid
fwrite(&b, sizeof(int), 1, f);
fwrite(&a, sizeof(int), 1, f);
// on remonte de deux infos pour lire le ppid précédent inscrit - 1 info = 4 octets
do
{ fseek (f, -16 , SEEK_CUR);
// lecture du ppid
fread(&c, sizeof(c), 1, f);
// comparaison des deux ppid
// si ils sont différents, on lit le pid, on envoie le signal au processus concerné
if (c!=b) {
fread (&p, sizeof(p), 1, f);
kill (p, SIG_QUIT)
}
// et on remonte de deux infos tant que l'on trouve un ppid différent
} while (c!=b);
// sinon, on ferme le fichier
// fermeture du fichier
fclose(f);
// on délock
flock (f, LOCK_UN);
res++;
} while (read(pip1[0], buff, 4)>0;
exit(res);
}
// equipe 2
void pere2(){
// mise en place du timing
alarm(20);
while(1) {
// sélection des fichiers
rand_a_b(min, max);
// ecriture et transmission des n° de fichiers via un pipe
close(pip2[0]);
printf("[Père :]Ecriture dans le tube de communication 2.\n" );
write(pip2[1], &num_fichier, sizeof(int));
//EOF est envoyé aux processus lisant les données écrites dans le tube
close(pip2[1]);
}
}
void fils2(){
// initialisation de la variable permettant d'incrémenter le compteur avec le nombre de points gagnés
int res = 0;
// initialisation de la variable signal
int sig =0;
// a répéter tant que le pipe n'est pas vide et tant que la sortie n'est pas explicitement demandée
do {
// verifie si il a recut un signal SIG_QUIT
signal(SIGQUIT, verif);
if (sig==1) exit(0);
//lit le n° de fichier
close(pip2[1]);
printf("[Fils :]Attente de lecture\n" );
read(pip2[0], buff, 4);
printf("[Fils :]Contenu de la lecture : %s\n",buff);
close(pip2[0]);
// transforme le int num_fichier en string et creation du nom de fichier
char s[10];
sprintf(s,"F%d.bin",buff);
// ouverture du ficher en lecture / ecriture binaire / à la fin
f= fopen(s,ab+);
// verrou exclusif et non bloquant sur le fichier
int l;
l = flock(f, LOCK_EX | LOCK_NB);
//si l=-1 alors, le fichier est deja utilisé, mise en attente et nouvelle tentative :
if (l==-1) {
do {
sleep(5);
l = flock(f, LOCK_EX | LOCK_NB);} while (l==-1);
// pid et ppdi :
pid_t a = getpid();
pid_t b = getppid();
int c;
// ecriture du n° d'équipe (ppid) et du pid
fwrite(&b, sizeof(int), 1, f);
fwrite(&a, sizeof(int), 1, f);
// on remonte de deux infos pour lire le ppid précédent inscrit - 1 info = 4 octets
do
{ fseek (f, -16 , SEEK_CUR);
// lecture du ppid
fread(&c, sizeof(c), 1, f);
// comparaison des deux ppid
// si ils sont différents, on lit le pid, on envoie le signal au processus concerné
if (c!=b) {
fread (&p, sizeof(p), 1, f);
kill (p, SIG_QUIT)
}
// et on remonte de deux infos tant que l'on trouve un ppid différent
} while (c!=b);
// sinon, on ferme le fichier
// fermeture du fichier
fclose(f);
// on délock
flock (f, LOCK_UN);
res++;
} while (read(pip1[0], buff, 4)>0;
exit(res);
}
// utilitaires communs
int verif(int num_sig) {
if (num_sig==3) {
printf("je suis le processus %d et je suis mort", getpid());
sig=1;
return sig;
}
// réarme pour qu'unix ne repositionne pas le traitement par défaut
signal(num_sig, verif);
}
int rand_a_b(int min, int max){
num_fichier = rand()%(max-min)+min;
printf("n° de fichier à conquérir ", num_fichier );
return (num_fichier);
} |