You are on page 1of 3

TD1 : Processus UNIX

RS : Rseaux et Syst`mes e e
Deuxi`me anne e e Lobjectif de ce TD est dapprofondir les notions relatives aux processus et de les appliquer au cadre spcique dUnix. e

Cration de processus avec lappel syst`me fork e e

La commande fork() cre un processus ( ) du processus appelant (le ( ere) avec le mme proe (ls) (p` )), e gramme que ce dernier. La valeur renvoye par fork() est : e Au p`re : le numro (pid) du processus ls. e e Au ls : 0 (il peut retrouver le pid de son p`re avec getppid()) e En cas dchec (table des processus pleine), aucun processus nest cr, et la valeur 1 est renvoye. e ee e Dans la suite, nous supposerons que tous les appels russissent sans probl`me, mais une application relle e e e devrait bien entendu traiter les cas derreurs. Question 1. Quache lexcution du programme suivant : e
1 2 3 4 5 6 7 8 9 10 11 12 13

int main() { pid_t pid; int x = 1; pid = fork(); if (pid == 0) { printf("Dans fils : x=%d\n", ++x); exit(0); } printf("Dans p`re : x=%d\n", --x); e exit(0); }

Question 2. On consid`re les deux programmes suivants et leur schma dexcution. e e e Exemple 1 : un clonage
1 2 3 4 5

int main() { fork(); printf("hello!\n"); exit(0); }

hello hello fork

Exemple 2 : deux clonages


1 2 3 4 5 6

int main() { fork(); fork(); printf("hello!\n"); exit(0); }

hello hello
fork hello

hello
fork fork

Question : Illustrer lexcution de ce programme : e


1 2 3 4 5 6 7

int main() { fork(); fork(); fork(); printf("hello!\n"); exit(0); }

Question 3. Combien de lignes ( (hello !) imprime chacun des programmes suivants ? ) Programme 1 : Programme 2 : Programme 3 : Programme 4 :
1 1 2 3 4 5 6 7 8

int main() { int i; for (i=0; i<2; i++) fork(); printf("hello!\n"); exit(0); }

2 3 4 5 6 7 8 9 10

void doit() { fork(); fork(); printf("hello!\n"); } int main() { doit(); printf("hello!\n"); exit(0); }

1 2 3 4 5 6

int main() { if (fork()) fork(); printf("hello!\n"); exit(0); }

1 2 3 4 5 6 7

int main() { if (fork()==0) { if (fork()) { printf("hello!\n"); } } }

TD1 : Processus UNIX Question 4. On consid`re les deux structures de liation (cha et arbre) reprsentes ci-apr`s. e ne e e e
pid, ppid pid, ppid pid, ppid exit pid, ppid exit pid, ppid exit exit pid, ppid pid, ppid pid, ppid exit exit exit

exit

Ecrire un programme qui ralise une cha de n processus, o` n est pass en param`tre de lexcution de e ne u e e e la commande (par exemple, n = 3 sur la gure ci-dessus). Faire imprimer le numro de chaque processus e et celui de son p`re. Mme question avec la structure en arbre. e e

Relations entre processus p`re et ls e

Question 5. Le programme ci-apr`s lance un processus qui attend la n de ses ls et imprime leur e code de retour.
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

#define N 2 int main() { int status, i; pid_t pid; for (i = 0; i < N; i++) if ((pid = fork()) == 0) exit(100+i); /* fils */

/* le p`re attend la fin de ses fils */ e while ((pid = waitpid(-1, &status, 0)) > 0) { if (WIFEXITED(status)) if (WEXITSTATUS(status) == 0) { printf("Le fils %d sest termin normalement avec le code 0.\n",pid); e printf("Il na donc pas rencontr de probl`me.\n"); e e } else { printf("Le fils %d sest termin avec le code %d.\n",pid,WEXITSTATUS(status)); e printf("Il sagit en gnral dun code derreur (cf. la page man du processus dclanch)\n"); e e e e } else printf("Le fils %d sest termin a cause dun signal\n", pid); e ` } if (errno != ECHILD) perror("erreur dans waitpid"); exit(0); }

Modier ce programme pour quil traite les ls dans lordre dans lequel ils ont t crs (en achant leur e e ee code de retour). Question 6. On consid`re le programme suivant : e
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

int main() { int status; pid_t pid; fprintf(stderr,"Hello\n"); pid = fork(); fprintf(stderr,"%d\n", !pid); if (pid != 0) { if (waitpid(-1, &status, 0) > 0) { if (WIFEXITED(status) != 0) fprintf(stderr,"%d\n", WEXITSTATUS(status)); } } fprintf(stderr,"Bye\n"); exit(2); }

Combien de lignes ce programme imprime-t-il ? Discuter les ordres possibles dans lesquels ces lignes sont imprimes. e

TD1 : Processus UNIX

Excution dun programme e

La famille de primitives exec permet de crer un processus pour excuter un programme dtermin e e e e (qui a auparavant t plac dans un chier, sous forme binaire excutable). On utilise en particulier ee e e execvp pour excuter un programme en lui passant un tableau darguments. Le param`tre filename e e pointe vers le nom (absolu ou relatif) du chier excutable, argv vers le tableau contenant les arguments e (termin par NULL) qui sera pass ` la fonction main du programme lanc. Par convention, le param`tre e ea e e argv[0] contient le nom du chier excutable, les arguments suivants tant les param`tres successifs de e e e la commande.
1 2

#include <unistd.h> int execvp(char *filename, char *argv[]);

Noter que les primitives exec provoquent le ( (recouvrement) de la mmoire du processus appelant ) e par le nouveau chier excutable. Il ny a donc pas normalement de retour (sauf en cas derreur chier e inconnu ou permission auquel cas la primitive renvoie 1).
argv[] argv[0] argv[1] argv[argc -1] NULL
...

argv

"ls" "-lt"

"/"

Question 7. Que fait le programme suivant ?


1 2 3 4 5 6 7 8

#include<stdio.h> #include<unistd.h> #define MAX 5 int main() { char *argv[MAX]; argv[0] = "ls"; argv[1] = "-lR"; argv[2] = "/"; argv[3] = NULL; execvp("ls", argv); }

Question 8. Ecrire un programme doit qui excute une commande Unix quon lui passe en param`tre. e e Exemple :
1

doit ls -lt /

You might also like