Skip to content

Instantly share code, notes, and snippets.

@erickedji
Created November 16, 2011 05:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erickedji/1369340 to your computer and use it in GitHub Desktop.
Save erickedji/1369340 to your computer and use it in GitHub Desktop.
Exercices de la séance 5 - TP Systèmes Centralisés
/* Time-Stamp: <16 Oct 1997 12:42 charpov@enseeiht.fr> */
/* 8.9 */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MSG1 "Je suis le fils lent, lent, lent...\n"
#define MSG2 "Je suis le fils bavard, bla bla bla...\n"
#define BUF_SIZE 64
void handler_sigpipe (int unused)
{
fprintf (stderr, "Signal SIGPIPE\n");
exit (3);
}
int main (int argc, char *argv[])
{
int flent, fbavard; /* les deux processus fils. */
int plent[2], pbavard[2]; /* les deux tubes. */
int vlent, vbavard, vstd; /* indique si quels processus sont vivants. */
int nbiter; /* nbre de messages affichés par chaque fils */
if (argc > 2) {
fprintf (stderr, "Usage: %s [nb iter]\n", argv[0]);
exit (1);
}
nbiter = 10;
if (argc == 2)
nbiter = atoi (argv[1]);
signal (SIGPIPE, handler_sigpipe);
if (pipe (plent) == -1) {
perror ("pipe");
exit (2);
}
flent = fork ();
if (flent == -1) {
perror ("fork");
exit (2);
}
if (flent == 0) { /* fils lent */
int lmsg1;
int i;
lmsg1 = strlen (MSG1);
close (plent[0]);
for (i = 0; i < nbiter; i++) {
if (write (plent[1], MSG1, lmsg1) == -1) {
perror ("write");
exit (3);
}
sleep (5);
}
exit (0);
}
/* Père */
close (plent[1]);
if (pipe (pbavard) == -1) {
perror ("pipe");
exit (2);
}
fbavard = fork ();
if (fbavard == -1) {
perror ("fork");
exit (2);
}
if (fbavard == 0) { /* fils bavard */
int lmsg2;
int i;
lmsg2 = strlen (MSG2);
close (plent[0]);
close (pbavard[0]);
for (i = 0; i < nbiter; i++) {
if (write (pbavard[1], MSG2, lmsg2) == -1) {
perror ("write");
exit (3);
}
sleep (2);
}
exit (0);
}
/* pere */
close (pbavard[1]);
vlent = 1;
vbavard = 1;
vstd = 1;
while (vstd || vlent || vbavard) {
fd_set readfds; /* l'ensemble des descripteurs à écouter. */
int nb_a_lire; /* combien de descr où lecteur possible. */
struct timeval timeout; /* délai d'attente pour le select. */
char buf[BUF_SIZE]; /* tampon pour la recopie. */
FD_ZERO (&readfds);
if (vstd)
FD_SET (0, &readfds);
if (vlent)
FD_SET (plent[0], &readfds);
if (vbavard)
FD_SET (pbavard[0], &readfds);
timerclear (&timeout);
timeout.tv_sec = 10;
nb_a_lire = select (FD_SETSIZE, &readfds, NULL, NULL, &timeout);
if (nb_a_lire == -1) {
perror ("select");
exit (3);
}
if (nb_a_lire != 0)
printf ("Quelque chose a lire sur %d descripteur%s...\n",
nb_a_lire, (nb_a_lire > 1)?"s":"");
else
printf ("Rien depuis 10 secondes...\n");
if (vstd && FD_ISSET (0, &readfds)) {
int r;
r = read (0, buf, BUF_SIZE);
if (r == -1) {
perror ("read");
exit (3);
} else if (r == 0) {
printf ("**** Mort de l'entree standard.\n");
vstd = 0;
} else {
write (1, buf, r);
}
}
if (vlent && FD_ISSET (plent[0], &readfds)) {
int r;
r = read (plent[0], buf, BUF_SIZE);
if (r == -1) {
perror ("read");
exit (3);
}
if (r != 0) {
write (1, buf, r);
} else if (r == 0) {
printf ("**** Mort du fils lent.\n");
vlent = 0;
} else {
write (1, buf, r);
}
}
if (vbavard && FD_ISSET (pbavard[0], &readfds)) {
int r;
r = read (pbavard[0], buf, BUF_SIZE);
if (r == -1) {
perror ("read");
exit (3);
}
if (r != 0) {
write (1, buf, r);
} else if (r == 0) {
printf ("**** Mort du fils bavard.\n");
vbavard = 0;
} else {
write (1, buf, r);
}
}
}
exit (0);
}
/* Time-stamp: <02 Sep 2008 10:40 queinnec@enseeiht.fr> */
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h> /* pour mkdir */
#include <sys/wait.h> /* pour wait */
#define NMAX 1000
int main()
{
int n1, n2, n3;
char *dirw;
/* création du répertoire de travail */
dirw = "RESTMP";
if (mkdir (dirw, 0766) == -1) {
perror ("mkdir");
exit (1);
}
/* création de 2 fils */
n1=fork();
if (n1 == -1) {
perror ("fork1");
exit(2);
}
/* un processus fils1 a été créé */
if (n1 != 0) { /* processus père */
n2=fork();
if (n2 == -1) {
perror ("fork2");
exit(2);
}
if (n2 != 0) { /* processus père */
int retw1, retw2;
/* attente de la fin des fils */
printf("attente de la fin des fils\n");
retw1 = wait (NULL);
printf("fin du processus %d\n", retw1);
retw2 = wait (NULL);
printf("fin du processus %d\n", retw2);
printf("creation du processus nettoyeur \n");
/* création d'un processus nettoyeur. */
n3=fork();
if (n3 == -1) {
perror ("fork3");
exit(2);
}
if (n3 != 0) { /* processus père */
/* attente fin du processus nettoyeur */
wait (NULL);
printf("fin du processus nettoyeur\n");
/* destruction du répertoire de travail */
if (rmdir(dirw) == -1)
perror ("rmdir");
} else {
/* processus nettoyeur */
execlp ("sh", "sh", "-c", "/bin/rm RESTMP/*", NULL);
}
} else { /* processus fils 2 */
int fd;
printf("--> getpid dans processus fils 2 = %d\n", (int) getpid());
if (chdir (dirw) == -1) {
perror ("chdir1");
exit (3);
}
fd = open ("bidon2a", O_RDWR | O_CREAT | O_TRUNC, 0666);
if (fd == -1) {
perror ("bidon2a");
exit(3);
}
write(fd, "fils 2", 6);
sleep(2);
close(fd);
}
} else { /* processus fils 1 */
int fd;
printf("--> getpid dans processus fils 1 = %d\n", (int) getpid());
if (chdir (dirw) == -1) {
perror ("chdir1");
exit (3);
}
fd = open ("bidon1a", O_RDWR | O_CREAT | O_TRUNC, 0666);
if (fd == -1) {
perror ("bidon1a");
exit(3);
}
write (fd, "fils 1", 6);
sleep(2);
close(fd);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#define NB_DESC 256
int main(void)
{
int nb, p1[2], p2[2], p3[2];
fd_set fds;
int res;
struct timeval t_out;
if ( pipe(p1) == -1 )
{
fprintf(stderr,"Erreur creation premier pipe\n");
exit(1);
}
if ( fork() == 0 ) /* premier fils : appel errone */
{
close(1);
dup(p1[1]);
close(p1[0]);
close(p1[1]);
execl("transmet_v1","transmet_v1","1","2",NULL);
fprintf(stderr,"probleme execution premier exec\n");
}
/* pere */
close(p1[1]);
if ( pipe(p2) == -1 )
{
fprintf(stderr,"Erreur creation deuxieme pipe\n");
exit(2);
}
if ( fork() == 0 ) /* deuxieme fils : appel avec 10 */
{
close(p1[0]);
close(1);
dup(p2[1]);
close(p2[0]);
close(p2[1]);
execl("transmet_v1","transmet_v1","10",NULL);
fprintf(stderr,"probleme execution deuxieme exec\n");
}
/* pere */
close(p2[1]);
if ( pipe(p3) == -1 )
{
fprintf(stderr,"Erreur creation troisieme pipe\n");
exit(3);
}
if ( fork() == 0 ) /* troisieme fils : appel avec 7 */
{
close(p1[0]);
close(p2[0]);
close(1);
dup(p3[1]);
close(p3[0]);
close(p3[1]);
execl("transmet_v1","transmet_v1","7",NULL);
fprintf(stderr,"probleme execution troisieme exec\n");
}
close(p3[1]);
sleep(2);
FD_ZERO(&fds);
FD_SET(p1[0], &fds);
FD_SET(p2[0], &fds);
FD_SET(p3[0], &fds);
timerclear(&t_out);
t_out.tv_sec=3;
res= select(NB_DESC, &fds,NULL,NULL,&t_out);
printf("retour de select=%d\n",res);
if ( res >= 1 )
{
if ( FD_ISSET(p1[0], &fds) )
{
printf("fils1 a ecrit ->");
read(p1[0],&nb,sizeof(int));
printf("%d\n",nb);
}
if ( FD_ISSET(p2[0], &fds) )
{
printf("fils2 a ecrit ->");
read(p2[0],&nb,sizeof(int));
printf("%d\n",nb);
}
if ( FD_ISSET(p3[0], &fds) )
{
printf("fils3 a ecrit ->");
read(p3[0],&nb,sizeof(int));
printf("%d\n",nb);
}
}
else
{
printf("select : timeout\n");
}
printf("le pere a fini\n");
exit(0);
}
/*************************************
%version1
retour de select=3
fils1 a ecrit ->-1
fils2 a ecrit ->10
fils3 a ecrit ->7
le pere a fini
*************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#define NB_DESC 256
#define TRUE 1
#define FALSE 0
int main(void)
{
int nb, p1[2], p2[2], p3[2];
fd_set fds;
int res, mort1, mort2, mort3;
struct timeval t_out;
if ( pipe(p1) == -1 )
{
fprintf(stderr,"Erreur creation premier pipe\n");
exit(1);
}
if ( fork() == 0 ) /* premier fils : appel errone */
{
close(1);
dup(p1[1]);
close(p1[0]);
close(p1[1]);
execl("transmet_v2","transmet_v2","1","2",NULL);
fprintf(stderr,"probleme execution premier exec\n");
}
/* pere */
close(p1[1]);
if ( pipe(p2) == -1 )
{
fprintf(stderr,"Erreur creation deuxieme pipe\n");
exit(2);
}
if ( fork() == 0 ) /* deuxieme fils : appel avec 10 */
{
close(p1[0]);
close(1);
dup(p2[1]);
close(p2[0]);
close(p2[1]);
execl("transmet_v2","transmet_v2","10",NULL);
fprintf(stderr,"probleme execution deuxieme exec\n");
}
/* pere */
close(p2[1]);
if ( pipe(p3) == -1 )
{
fprintf(stderr,"Erreur creation troisieme pipe\n");
exit(3);
}
if ( fork() == 0 ) /* troisieme fils : appel avec 7 */
{
close(p1[0]);
close(p2[0]);
close(1);
dup(p3[1]);
close(p3[0]);
close(p3[1]);
execl("transmet_v2","transmet_v2","7",NULL);
fprintf(stderr,"probleme execution troisieme exec\n");
}
close(p3[1]);
sleep(2);
mort1= mort2= mort3= FALSE;
FD_ZERO(&fds);
FD_SET(p1[0], &fds);
FD_SET(p2[0], &fds);
FD_SET(p3[0], &fds);
timerclear(&t_out);
t_out.tv_sec=3;
res= select(NB_DESC, &fds,NULL,NULL,&t_out);
while ( !mort1 || !mort2 || !mort3 )
{
printf("retour de select=%d\n",res);
if ( res == 0 )
{
printf("select : timeout\n");
}
else
{
if ( !mort1 && FD_ISSET(p1[0], &fds) )
{
printf("fils1 a ecrit ->");
read(p1[0],&nb,sizeof(int));
printf("%d\n",nb);
mort1= TRUE;
}
if ( !mort2 && FD_ISSET(p2[0], &fds) )
{
printf("fils2 a ecrit ->");
read(p2[0],&nb,sizeof(int));
printf("%d\n",nb);
mort2= TRUE;
}
if ( !mort3 && FD_ISSET(p3[0], &fds) )
{
printf("fils3 a ecrit ->");
read(p3[0],&nb,sizeof(int));
printf("%d\n",nb);
mort3= TRUE;
}
}
FD_ZERO(&fds);
if ( !mort1 ) FD_SET(p1[0], &fds);
if ( !mort2 ) FD_SET(p2[0], &fds);
if ( !mort3 ) FD_SET(p3[0], &fds);
timerclear(&t_out);
t_out.tv_sec=3;
if ( !mort1 || !mort2 || !mort3 )
res= select(NB_DESC, &fds,NULL,NULL,&t_out);
}
printf("le pere a fini\n");
exit(0);
}
/*******************************************
%version2
retour de select=1
fils1 a ecrit ->-1
retour de select=0
select : timeout
retour de select=1
fils3 a ecrit ->7
retour de select=1
fils2 a ecrit ->10
le pere a fini
*******************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#define NB_DESC 256
#define TRUE 1
#define FALSE 0
int nb_vivants= 3;
void mort_fils(int num_sig_unused)
{
int pid_fils, ret;
signal(SIGCHLD,mort_fils);
nb_vivants--;
pid_fils= wait(&ret);
if ( WIFEXITED(ret) )
printf("Fils %d exit %d\n",pid_fils,WEXITSTATUS(ret));
else
printf("Fils %d signal %d\n",pid_fils,WTERMSIG(ret));
}
int main(void)
{
int ret, nb, p1[2], p2[2], p3[2];
fd_set fds;
int res, fils1_ecrit, fils2_ecrit, fils3_ecrit;
struct timeval t_out;
signal(SIGCHLD,mort_fils);
if ( pipe(p1) == -1 )
{
fprintf(stderr,"Erreur creation premier pipe\n");
exit(1);
}
if ( fork() == 0 ) /* premier fils : appel errone */
{
close(1);
dup(p1[1]);
close(p1[0]);
close(p1[1]);
execl("transmet_v2","transmet_v2","1","2",NULL);
fprintf(stderr,"Probleme execution premier exec\n");
}
/* pere */
close(p1[1]);
if ( pipe(p2) == -1 )
{
fprintf(stderr,"Erreur creation deuxieme pipe\n");
exit(2);
}
if ( fork() == 0 ) /* deuxieme fils : appel avec 10 */
{
close(p1[0]);
close(1);
dup(p2[1]);
close(p2[0]);
close(p2[1]);
execl("transmet_v2","transmet_v2","10",NULL);
fprintf(stderr,"Probleme execution deuxieme exec\n");
}
/* pere */
close(p2[1]);
if ( pipe(p3) == -1 )
{
fprintf(stderr,"Erreur creation troisieme pipe\n");
exit(3);
}
if ( fork() == 0 ) /* troisieme fils : appel avec 7 */
{
close(p1[0]);
close(p2[0]);
close(1);
dup(p3[1]);
close(p3[0]);
close(p3[1]);
execl("transmet_v2","transmet_v2","7",NULL);
fprintf(stderr,"Probleme execution troisieme exec\n");
}
close(p3[1]);
fils1_ecrit= fils2_ecrit= fils3_ecrit= FALSE;
FD_ZERO(&fds);
FD_SET(p1[0], &fds);
FD_SET(p2[0], &fds);
FD_SET(p3[0], &fds);
timerclear(&t_out);
t_out.tv_sec=3;
res= select(NB_DESC, &fds,NULL,NULL,&t_out);
while ( nb_vivants != 0 || !fils1_ecrit || !fils2_ecrit || !fils3_ecrit )
{
if ( res == 0 )
{
printf("select : timeout\n");
}
else
{
if ( res == -1 )
{
if ( errno == EINTR )
printf("select interrompu par la mort d'un fils\n");
else
{
printf("zarbi : select interrompu mais pas mort !\n");
exit(1);
}
}
printf("Analyse des donnees disponibles\n");
if ( !fils1_ecrit && FD_ISSET(p1[0], &fds) )
{
ret= read(p1[0],&nb,sizeof(int));
if ( ret == sizeof(int) )
{
printf("fils1 a ecrit %d ->%d\n",ret,nb);
fils1_ecrit= TRUE;
}
else
{ /* exemple : mort d'un autre fils */
printf("Lecture du premier fils interrompue\n");
}
}
if ( !fils2_ecrit && FD_ISSET(p2[0], &fds) )
{
ret= read(p2[0],&nb,sizeof(int));
if ( ret == sizeof(int) )
{
printf("fils2 a ecrit %d ->%d\n",ret,nb);
fils2_ecrit= TRUE;
}
else
{ /* exemple : mort d'un autre fils */
printf("Lecture du deuxieme fils interrompue\n");
}
}
if ( !fils3_ecrit && FD_ISSET(p3[0], &fds) )
{
ret= read(p3[0],&nb,sizeof(int));
if ( ret == sizeof(int) )
{
printf("fils3 a ecrit %d ->%d\n",ret,nb);
fils3_ecrit= TRUE;
}
else
{ /* exemple : mort d'un autre fils */
printf("Lecture du troisieme fils interrompue\n");
}
}
}
FD_ZERO(&fds);
if ( !fils1_ecrit ) FD_SET(p1[0], &fds);
if ( !fils2_ecrit ) FD_SET(p2[0], &fds);
if ( !fils3_ecrit ) FD_SET(p3[0], &fds);
timerclear(&t_out);
t_out.tv_sec=3;
if ( nb_vivants > 0 )
{
res= select(NB_DESC, &fds,NULL,NULL,&t_out);
}
else
{
printf("Plus de select\n");
}
/* si nb_vivants=0, on peut reboucler quand meme dans le cas
ou la lecture de la donnee n'a pas encore ete effectuee */
}
printf("le pere a fini apres ses fils\n");
exit(0);
}
/******************************************
%version3
Fils 2115 exit 0
Analyse des donnees disponibles
fils1 a ecrit 4 ->-1
select : timeout
select : timeout
Fils 2117 exit 0
Analyse des donnees disponibles
fils3 a ecrit 4 ->7
Fils 2116 exit 0
Analyse des donnees disponibles
fils2 a ecrit 4 ->10
Plus de select
le pere a fini apres ses fils
******************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int param, ret;
if ( argc != 2 ) { /* bon nombre de parametres ? */
param = -1;
} else {
ret = sscanf(argv[1], "%d", &param);
if ( ret != 1 ) /* valeur numerique ? */
param = -1;
}
write(1, &param, sizeof(int));
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int param, ret;
if ( argc != 2 ) { /* bon nombre de parametres ? */
param = -1;
} else {
ret = sscanf(argv[1],"%d",&param);
if ( ret != 1 ) /* valeur numerique ? */
param = -1;
else
sleep(param);
}
write(1,&param,sizeof(int));
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment