You are on page 1of 6

INF3600: Systèmes d’exploitation

Contrôle périodique

Aut 2005

École Polytechnique de Montréal Département de Génie Informatique Cours INF3600 : Systèmes d’exploitation Contrôle périodique Automne 2005

• • • •

Date : 21 octobre 2005 de 18h30 à 20h30 Professeurs : Hanifa Boucheneb, Niculina Ignat Documentation permise Calculatrices programmables et cellulaires non permis

• • •

Pondération : 30 % Nbre. de questions : 5 Total : 20 points

Question 1 (4 pts) : Généralités
Répondez aux questions suivantes (maximum 5 lignes par question). Les réponses doivent être concises. 1. Un processus peut passer directement de l’état bloqué dans l’état exécution. Vrai ou faux? Justifiez. Faux. Lorsqu’un processus bloqué est débloqué, il passe d’abord à l’état prêt. L’ordonnanceur lancera son exécution plus tard, en fonction de la politique d’ordonnancement. 2. Lorsqu’un processus demande l’ouverture d’un pipe nommé en lecture (respectivement en écriture), il est bloqué jusqu’à ce qu’un autre processus demande l’ouverture du pipe en écriture (respectivement en lecture). Citez un problème qui pourrait survenir si le système n’imposait pas cette synchronisation à l’ouverture des pipes. Si un processus écrit dans le pipe alors que celui-ci n’a pas été encore ouvert, le signal SIGPIPE est généré; ce qui va mettre fin au processus. 3. Un moniteur est un module spécial pour l’exclusion mutuelle, dont toutes les données et les procédures sont publiques. Vrai ou faux? Justifiez. Page 1 sur 6

n=3. return 0. La désactivation de l’ordonnanceur protège un processus qui accède à une section critique contre les autres processus. Un processus peut appeler les procédures du moniteur. } 1) Complétez le code précédent de manière qu’il crée l’arborescence illustrée ci-dessous : P F3 F1 F2 F4 F5 F6 F7 Les processus fils du dernier niveau se transforment en a (a est un fichier exécutable). mais pas contre les interruptions (qui pourraient accéder elles-mêmes à la section critique). n=3. pour accéder aux sections critiques. Question 2 (4 pts) : Processus Considérez le programme suivant: int main ( ) { pid_t pid. L’exclusion mutuelle peut être réalisée par la désactivation de l’ordonnanceur. i<n. i<n. Les données sont privées. int main ( ) { pid_t pid. for (i=0. Vrai ou faux? Justifiez. getpid()). i++) { /*1*/ pid = fork(). Les autres processus fils affichent à l’écran le message « je continue » avant de poursuivre la création de processus. i++) { /*1*/ } while (wait(NULL) >= 0).INF3600: Systèmes d’exploitation Contrôle périodique Aut 2005 Faux. Page 2 sur 6 . mais n’a pas le droit d’accéder directement aux données internes au moniteur. for (i=0. int i. Faux. 4. int i. printf("processus racine %d\n".

} } while (wait(NULL) >= 0). else printf(" Je continue %d\n". } 2) Tracez l’arborescence des processus créés par le programme si l’on supprime la ligne while (wait(NULL) >= 0). NULL). exit(0). if( i == n-1) execlp("a".getppid()). return 0. printf(" Je suis un père %d\n". getpid()). }else { if(pid==-1) exit(1). P F1 F2 F3 Page 3 sur 6 . getpid().INF3600: Systèmes d’exploitation Contrôle périodique Aut 2005 if(pid==0) { printf("creation d'un processus %d par %d\n". getpid()). "a". le père exécute les instructions : wait(NULL). et à la suite de la création de chaque fils.

execvp(argv[1]. Complétez le code de manière à exécuter. int main(int argc. argv[3]=NULL. exit(0). l’un après l’autre. /*2*/ } /*3*/ if (fork()==0) { /*4*/ execvp(argv[2]. exit(0).O_CREAT|O_WRONLY)) < 0) { perror("error"). On récupérera ainsi dans ce fichier les résultats du premier exécutable suivis de ceux du deuxième. } Page 4 sur 6 . execvp(argv[2]. /*5*/ } /*6*/ } int main(int argc. exit(0). } if (fork()==0) { close(1). perror("Error EXECVP").1). &argv[1]). Ce programme crée deux processus pour exécuter les deux fichiers exécutables. close(fd).1). close(fd). &argv[2]). dup2(fd. &argv[2]). } wait(NULL). argv[2] = NULL. les deux fichiers exécutables et à rediriger les sorties standards des deux exécutables vers le fichier spécifié comme troisième paramètre. perror("Error EXECVP"). if ( (argc!=4) or (fd = open(argv[3]. char* argv[]) { /*0*/ if (fork()==0) { /*1*/ execvp(argv[1]. } wait(NULL). if (fork()==0) { close(1). dup2(fd.INF3600: Systèmes d’exploitation Contrôle périodique Aut 2005 Question 3 (3 pts) : Redirection des sorties standards Considérez le programme suivant qui a en entrée trois paramètres : deux fichiers exécutables et un nom de fichier. &argv[1]). char* argv[]) { int fd.

2. } sigintF() { signal(SIGINT. les processus père et fils ne se terminent pas immédiatement. sigintP).sigalrm). le père affiche son identificateur PID (sans se terminer). sigintP). while(1) { printf (“ici fils \n”). alarm(5). } Complétez le code précédent de manière à réaliser les traitements suivants : 1. sigintF). mais après un délai de 5 secondes. Lorsque l’utilisateur presse les touches Ctrl-C. sleep(1). le fils effectue un appel système alarm(5) qui envoie automatiquement le signal SIGALRM après 5 secondes. } int main(void) { signal(SIGCHLD. if (fork() == 0) { signal(SIGINT. exit(0). } return 0. signal(SIGINT. signal(SIGALRM. Si l’utilisateur presse les touches Ctrl-C lorsque le programme s’exécute. exit(1). sigchld). sleep(1). } Page 5 sur 6 .INF3600: Systèmes d’exploitation Contrôle périodique Aut 2005 Question 4 (3 pts) : Signaux Considérez le programme suivant : void sigintP(int sig) { /*1*/ } void sigalrm(int sig) { /*2*/ } void sigintF(int sig) { /*3*/ } void sigchld(int sig) { wait(NULL). SIG_IGN).getpid()). printf(“ici pere \n”). } } while(1) { signal(SIGINT. sigintP() { } sigalrm() { printf("pid=%d\n".

recevoir(rep) . recevoir (mess) . La réponse de B doit être récupérée par le processus expéditeur du message. /* 2*/ V(WM) .INF3600: Systèmes d’exploitation Contrôle périodique Aut 2005 Question 5 (6 pts) : Synchronisation Deux processus A et B communiquent au moyen d’un tampon T pouvant contenir qu’un seul message à la fois. //construit et dépose un message dans T void recevoir(char buf[] ) . et ainsi de suite… 1) Synchronisez au moyen de sémaphores les processus A et B. V(mutex). rep[256] . } . de façon alternée. /*3*/ } } } while (1) { /* 4 */ P(WM). rep[256] . // récupère un message de T Processus A ou C Processus B { char mess[256]. /*0*/ char T[256] . Pour répondre à la question. while (1) { P(mutex). /*5*/ envoyer(rep). P(WR) . while (1) { /* 1 */ envoyer (mess ) . V(WR) . et ainsi de suite… Lorsque B reçoit un message de A. pour la communication dans les deux sens (attention un seul processus utilise à la fois ce tampon). P(WR) . rep[256] . Les processus A et C se comportent de la même manière. void envoyer (char buf[] ) .WR=0. il envoie un autre message à B. B peut donc recevoir un message de A ou de C. { char mess[256] . char T[256] . envoyer (mess ) . Le processus A envoie un message via le tampon à B puis attend la réponse de B. } } } Page 6 sur 6 while (1) { P(WM). complétez le pseudocode suivant : semaphore WM=0. recevoir(rep) . { char mess[256] . V(WM) . //construit et dépose un message dans T void recevoir(char buf[] ) .WR=0. Ce tampon est utilisé. Synchronisez au moyen de sémaphores les processus A. rep[256] . il envoie sa réponse à A avant de se mettre en attente d’un autre message de A. // récupère un message de T Processus A Processus B { char mess[256]. envoyer(rep). /* 6*/ V(WR) . mutex=1. recevoir (mess) . void envoyer (char buf[] ) . À la réception de la réponse. B et C. } 2) Supposez maintenant qu’un troisième processus C désire communiquer avec B en utilisant l’unique tampon T. Pour répondre à la question complétez le pseudocode suivant : /*0*/ semaphore WM=0.