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
| #include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
#include <bits/signum.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 5
int liste_pid[N];
int *list_tube[N];
int continu = 1; // je suis pas sur que ca soit bien utile
typedef struct Message
{
int kind; // type de message, election / élu surement 1 / 0 on verra
int id; // id du fils
int valeur; // la valeur du vote
} message_t;
void handler ( int signalRecu, siginfo_t* info, void* pasUtileIci )
{
switch ( signalRecu )
{
case SIGUSR1:
{
printf ( "message reçu par le fil au pid %d\n", getpid() );
break;
}
case SIGTERM:
continu = 0;
}
}
int foo ( const char *whoami )
{
printf ( "Je suis %s. Mon pid est: %d mon ppid is %d\n",
whoami, getpid(), getppid() );
return 1;
}
int main ( void )
{
// creation des tubes.
for ( int i=0; i<N; ++i )
{
list_tube[i] = ( int * ) malloc ( 2* sizeof ( int ) );
pipe ( list_tube[i] );
}
// juste pour le débug, etre sur que chaque tube est unique.
// on print juste le coté lecture
for ( int i=0; i<N; ++i )
{
printf ( "descripteur de fichier %d\n", list_tube[i][0] );
}
/***************************************************/
/* Création de la structure pour gérer les signaux */
/***************************************************/
struct sigaction prepaSignal;
prepaSignal.sa_sigaction=&handler;
prepaSignal.sa_flags=SA_SIGINFO | SA_RESTART; // Ne pas oublier l'instruction wait du père
sigemptyset ( &prepaSignal.sa_mask );
pid_t pid;
foo ( "parent" );
for ( unsigned i=0; i < N; ++i )
{
pid_t pid=fork();
if ( pid==0 ) /* only execute this if child */
{
sigaction ( SIGUSR1, &prepaSignal, NULL );
sigaction ( SIGTERM, &prepaSignal, NULL );
foo ( "enfant" );
/*
* tube[0] lecture
* tube[1] ecriture
*/
int tube_lect = list_tube[i][0];
int tube_ecrit ;
if ( N - 1 != i )
{
tube_ecrit = list_tube[i% ( N -1 ) +1][1];
}
else
{
tube_ecrit = list_tube[0][1];
}
// on laiss le temps au Daron de faire tout les Fils
sleep ( 1 );
if ( 0 == i )
{
pause(); // on attend le signal pour commencer.
message_t premier_message;
premier_message.id = 0;
premier_message.kind = 1;
premier_message.valeur = 0;
write ( tube_ecrit, &premier_message, sizeof ( message_t ) ); // on envoit un premier message, avec une valeur la plus basse. il serai bien d faire un random [ 1 ; 30 [ par exemple
}
while ( continu )
{
message_t message;
read ( tube_lect,&message, sizeof ( message_t ) );
printf ( "je suis le fils %d je viens de lire dans le tube %d la valeur %d et l'id est %d\n", i, tube_lect, message.valeur, message.id );
message.valeur++;
message.id = i;
write ( tube_ecrit, &message, sizeof ( message_t ) );
if ( message.valeur > 20 )
continu = 0;
}
exit ( i );
} // fin du Fils
// Père
else
{
liste_pid[i] = pid;
}
} // fork()
/*
* apres la creation des N fils
*/
if ( pid != 0 ) // on est bien le père
{
sleep ( 5 ); // demande d'attente de 5 seconde avant d'envoyer le message du début
printf ( "j'envois le signal\n" );
kill ( liste_pid[0], SIGUSR1 );
// il va faloir attendre un signal du fils vaiqueur mais pour le moment ça va bien
for ( int i=0; i<N; ++i )
{
printf ( "je tattends enfant %d avec ton PID %d\n", i, liste_pid[i] );
wait ( &liste_pid[i] );
}
/*
* on supprime de la mémoire les tubes
*/
for ( int i=0; i<N; ++i )
{
free ( list_tube[i] );
}
}
return 0;
} |