effa | Bonjour, J'ai amélioré les choses (j'espere) grace à vous. j'aimerais suivre tes conseils shaoyin, mais je ne vois pas comment faire dans la mesure, ou d'apres moi il me faut deux pipes, et que ces deux pipes doivent etre declarees en dehors du main pour une question de portée, non ?
du coup, je suis obligée de faire deux fonctions : pere1 et pere2 et fils1 et fils2
non ????
Soyez indulgents, je debute, je stresse et j'ai mon exam qui arrive
Code :
- #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);
- }
|
|