INF2610 Contrôle périodique Automne École Polytechnique de Montréal. Département de Génie Informatique et Génie Logiciel.

Documents pareils
École Polytechnique de Montréal. Département de Génie Informatique et Génie Logiciel. Cours INF2610. Contrôle périodique.

Introduction aux Systèmes et aux Réseaux

Cours 6 : Tubes anonymes et nommés

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Programmation système en C/C++

Cours de Systèmes d Exploitation

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

Programmation système de commandes en C

Bases de programmation. Cours 5. Structurer les données

Cours Programmation Système

Algorithmique et Programmation, IMA

Problèmes liés à la concurrence

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

TRAVAUX PRATIQUES Programmation Système Langage C / Système UNIX. 2 e année Génie Informatique

Les structures de données. Rajae El Ouazzani

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Les processus légers : threads. Système L3, /31

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Introduction à la programmation concurrente

LEs processus coopèrent souvent pour traiter un même problème. Ces

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

3IS - Système d'exploitation linux - Programmation système

Les structures. Chapitre 3

Plan global. Programmation système II. Socket du domaine UNIX. Plan. Socket UNIX, Terminaux, Async IO, Mémoire, ELF.

Communication Interprocessus

Conventions d écriture et outils de mise au point

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Structure d un programme

Playing with ptrace() for fun and profit

Le système de gestion des fichiers, les entrées/sorties.

ACTIVITÉ DE PROGRAMMATION

Cours de Programmation Impérative: Zones de mémoires et pointeurs

Java Licence Professionnelle CISII,

Programme Compte bancaire (code)

Les chaînes de caractères

Les processus. Système L3, /39

INITIATION AU LANGAGE JAVA

ARDUINO DOSSIER RESSOURCE POUR LA CLASSE

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Programmation système

1 Mesure de la performance d un système temps réel : la gigue

Le prototype de la fonction main()

1 Lecture de fichiers

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Les arbres binaires de recherche

Les fichiers. Chapitre 4

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Introduction au langage C

Plan du cours. Historique du langage Nouveautés de Java 7

Cours Informatique Master STEP

Programmation client-serveur sockets - RPC

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Rappels Entrées -Sorties

Exercices INF5171 : série #3 (Automne 2012)

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Programmation en langage C d un µcontrôleur PIC à l aide du compilateur C-CCS Sommaire

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Notions fondamentales du langage C# Version 1.0

Cours de Système : Gestion de Fichiers

Propagation sur réseau statique et dynamique

CONFIGURATION DE L AUTOMATE SIEMENS

Les processus 2/54. Qu est-ce qu un processus? 3(6)/54. Se souvenir 1(1)/54. Le système de fichiers (exemple du disque dur)

Synchro et Threads Java TM

Temps Réel. Jérôme Pouiller Septembre 2011

COMPARAISONDESLANGAGESC, C++, JAVA ET

Communication inter-processus (IPC) : tubes & sockets. exemples en C et en Java. F. Butelle

OS Réseaux et Programmation Système - C5

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Cours 2: Exclusion Mutuelle entre processus (lourds, ou légers -- threads)

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

MPI Activité.10 : Logique binaire Portes logiques

Flux de données Lecture/Ecriture Fichiers

Programmation impérative

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

Projet gestion d'objets dupliqués

Recherche dans un tableau

Programmation en langage C

TD3: tableaux avancées, première classe et chaînes

Systèmes d exploitation Gestion de processus

Exercice sur les Dockers

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Langage propre à Oracle basé sur ADA. Offre une extension procédurale à SQL

INF6500 : Structures des ordinateurs. Sylvain Martel - INF6500 1

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Développement Logiciel

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Classes et Objets en Ocaml.

KL5121. Pour activer des sorties en fonction de la position d'un codeur

STAGE IREM 0- Premiers pas en Python

NIVEAU D'INTERVENTION DE LA PROGRAMMATION CONCURRENTE

1. Fonctionnement de l Internet 2. Protocoles applicatifs 3. Programmation réseau

Premiers Pas en Programmation Objet : les Classes et les Objets

Pilotes matériels sous Linux : mode noyau versus mode utilisateur

Transcription:

École Polytechnique de Montréal Département de Génie Informatique et Génie Logiciel Cours INF2610 Noyau d un système d exploitation Contrôle périodique Automne 2015 Date : 30 octobre de 18h à 20h Professeur : Hanifa Boucheneb Toute documentation permise Pondération : 30 % Nombre de questions : 3 Total : 20 points Calculatrices, cellulaires, ordinateurs non permis Page 1 sur 7

Question 1 : (7 pts) Généralités Supposez un processus principal PP composé d un ensemble de threads gérés par le noyau. Justifiez vos réponses à toutes les questions suivantes. a) [2.5 pts] Indiquez pour chaque événement suivant l effet sur le thread à l origine de l événement, les autres threads du processus ou/et le processus (la réponse à chaque sous question doit être claire et concise de maximum 4 lignes) : 1- Un thread de PP modifie une variable globale du processus PP. La variable est partagée par tous les threads. La modification de cette variable par un thread sera visible par tous les autres. 2- Un thread de PP se termine par exit. Le processus et tous ses threads vont se terminer (exit termine un processus). 3- Un thread de PP crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, puis ferme le descripteur de lecture du pipe. Le pipe devient non accessible en lecture. 4- Un thread de PP crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe puis lit du pipe : «while( read(fd[0],&c,1) >0) write(1,&c,1) ;». L appel read(fd[0],&c,1) va bloquer le thread car il y a toujours un écrivain. 5- Un thread de PP crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, ferme le descripteur d écriture puis lit du pipe : «while( read(fd[0],&c,1) >0) write(1,&c,1) ;». Le pipe est vide et n a aucun écrivain. L appel read(fd[0],&c,1) va retourner 0 (une fin de fichier). 6- Un thread de PP crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, ferme le descripteur de lecture fd[0] puis écrit dans le pipe : «write(fd[1], &c,1);». Le pipe n a aucun écrivain. L appel write(fd[1], &c,1) va générer un signal SIGPIPE qui mettra fin au processus et ses threads. 7- Un thread de PP crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, puis exécute l instruction «dup2(fd[1],1);». La sortie standard du processus et de ses threads devient le pipe car tous les threads d un processus partagent la table des descripteurs de fichiers du processus. 8- Un thread th1 de PP crée un autre thread th2 en lui passant comme paramètre l adresse d une variable locale v du thread th1. Le thread th2 modifie la variable Page 2 sur 7

v. Tous les threads d un processus partagent l espace d adressage du processus. La modification de v par th2 sera donc visible par th1 (th2 pourra accéder à v tant que th1 n a pas terminé son exécution). 9- Un thread appelle la fonction «pause() ;». Seul le thread appelant passe à l état bloqué car le noyau alloue du temps CPU aux threads noyau. b) [2.25 pts] Supposez maintenant que les threads sont implémentés au niveau utilisateur, indiquez parmi les événements précédents, ceux dont l effet est différent. Tous les threads utilisateur du processus partagent l espace d adressage et la table de descripteurs de fichiers du processus. Par contre, dans ce cas, le noyau alloue du temps CPU au processus. Si un thread du processus effectue un appel système bloquant, le processus passe à l état bloqué. Les événements 4 et 9 (qui se traduisent en un appel système bloquant) vont bloquer tout le processus. Les autres événements ont le même effet qu en a). c) [2.25 pts] Supposez finalement que les threads sont remplacés par des processus fils du processus principal. Indiquez, pour chacun des événements précédents, à l exception de l événement 8, l effet sur le processus fils à l origine de l événement et les autres. Les processus fils ne partagent ni l espace d adressage, ni la table de descripteurs de fichiers du processus père. Lorsqu un processus fils est créé, l espace d adressage et la table de descripteurs de fichiers du père «sont clonés» pour le fils, selon le principe «copie-on-write». Le noyau alloue du temps CPU à chaque processus (père et fils). Par conséquent : 1- Un processus modifie une variable globale. La modification d une variable globale du processus sera visible que pour le processus lui même. 2- Un processus se termine par exit. Le processus passe à l état zombie. Les autres processus pourront continuer leurs exécutions. 3- Un processus crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, puis ferme le descripteur de lecture du pipe. Le pipe devient non accessible en lecture. Il est non accessible pour PP et les autres processus fils. 4- Un processus crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe puis lit du pipe «while( read(fd[0],&c,1) >0) write(1,&c,1) ;». L appel read(fd[0],&c,1) va bloquer le processus appelant (uniquement). Page 3 sur 7

5- Un processus crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, ferme le descripteur d écriture puis lit du pipe «while( read(fd[0],&c,1) >0) write(1,&c,1) ;». Le pipe est vide et n a aucun écrivain, l appel read(fd[0],&c,1) va retourner 0 (une fin de fichier) pour le processus appelant. 6- Un processus crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, ferme le descripteur de lecture fd[0] puis écrit dans le pipe «write(fd[1], &c,1);». L appel write(fd[1], &c,1) va générer un signal SIGPIPE qui mettra fin au processus appelant (uniquement). 7- Un processus crée un pipe, en récupérant dans une variable globale «int fd[2];» les deux descripteurs de fichiers du pipe, puis exécute l instruction «dup2(fd[1],1);». La sortie standard du processus appelant (uniquement) devient le pipe. 8-9- Un processus appelle la fonction «pause() ;». Seul le processus appelant passe à l état bloqué. Question 2 (6.5 pts) : Processus & tubes de communication Considérez le code suivant : int i; char A[4]= ABC ; int main() for(i=0; i<2; i++) if (fork()==0) printf("%c \n", A[i]); else if (i==0) printf("%c", A[i]); exit(0); a) [2 pts] Donnez le nombre de processus créés par la fonction «main» ci-dessus ainsi que l arborescence de ces processus. Indiquez, sur cette arborescence, les symboles affichés à l écran par chacun des processus, y compris le processus principal. 3 processus sont crées. Page 4 sur 7

PP crée deux fils F1 (affiche A avec un saut de ligne) et F2 (affiche AB avec un saut de ligne) PP affiche A. F1 crée F11 (affiche B avec un saut de ligne) b) [1.5 pt] Modifiez le code afin de forcer chaque processus père à attendre la fin de tous ses fils avant de se terminer. int i; char A[4]= ABC ; bool parent; int main() for(i=0; i<2; i++) if (fork()==0) printf("%c \n", A[i]); parent=false; else if (i==0) printf("%c", A[i]); parent = true; if (parent) while(wait(null)>0); exit(0); c) [3 pts] Complétez le code initial de manière à ce que : - les «printf» des différents processus fils soient redirigés vers un tube anonyme, créé par le processus principal et - le processus principal lit et affiche à l écran toutes les données insérées dans le pipe par les processus créés, juste avant de se terminer. int i; char A[4]= ABC ; int fd[2]; bool pp=true; // pp=true pour le processus principal int main() pipe(fd); for(i=0; i<2; i++) if (fork()==0) if (pp) dup2(fd[1],1); close(fd[1]); close(fd[0]); pp=false; printf("%c \n", A[i]); else if (i==0) printf("%c", A[i]); if (pp) char C; close(fd[1]); while(read(fd[0], &C,1))>0) write(1,&c,1); close(fd[0]; else fflush(stdout); close(1); exit(0); Page 5 sur 7

Question 3 (6.5 pts) : Synchronisation des processus a) [3 pts] Considérez la solution, utilisant les sémaphores, au problème producteurs/consommateurs, pour le cas de 2 producteurs P1 et P2, et un consommateur C. const int N=100 ; int tampon [N]; int ip=0; Semaphore libre=n, occupe=0, mutex=1; Producteur_Pi ( ) // i=1,2 while (1) P(libre) ; produire(tampon, ip); ip = Mod(ip +1,N); V(occupe); Consommateur_C ( ) int ic=0; while (1) P(occupe); consommer(tampon,ic); ic= Mod(ic+1, N); V(libre); 1- [1.5 pt] Modifiez ce code pour que les producteurs P1 et P2 produisent en alternance dans le tampon (une production de P1 suivie d une production de P2, ). Le code du consommateur est le même. Pour les producteurs, deux sémaphores supplémentaires sont utilisés pour forcer l ordre des productions. const int N=100 ; int tampon [N]; int ip=0; Semaphore libre=n, occupe=0, mutex=1, S1=1, S2=0; Producteur_P1( ) while (1) P(S1) ; P(libre) ; produire(tampon, ip); ip = Mod(ip +1,N); V(occupe); V(S2) ; Producteur_P2( ) while (1) P(S2) ; P(libre) ; produire(tampon, ip); ip = Mod(ip +1,N); V(occupe); V(S1) ; 2- [1.5 pt] Est-il plus intéressant d utiliser deux tampons (un tampon pour chaque producteur) et de forcer le consommateur à consommer en alternance des tampons de P1 et P2 (en commençant par celui de P1)? Justifiez votre réponse. Page 6 sur 7

Dans la solution précédente, il ne peut y avoir de productions ou consommations en parallèle (une à la fois). L utilisation de deux tampons permet aux producteurs de produire en parallèle. Pendant qu un producteur (ou le consommateur) utilise un tampon, l autre producteur pourrait produire dans l autre tampon. Les producteurs et le consommateur passeront ainsi moins de temps à l état bloqué. De ce point de vue, cette solution est plus intéressante. Elle nécessite par contre plus de ressources : 2 tampons, 4 sémaphores compteurs (libre1, libre2, occupe1, occupe2) et 2 sémaphores binaires (mutex1, mutex2) vs. 1 tampon, 2 sémaphores compteurs (libre, occupe) et 3 sémaphores binaires (mutex, S1, S2). b) [3.5 pts] On veut implémenter les sémaphores compteurs sem_c en utilisant les sémaphores binaires sem_b. Complétez la structure sem_c et les fonctions Init, P et V suivantes. Supposez que vous disposez des fonctions Initb (sem_b S, int v), Pb(sem_b S) et Vb(sem_b S) qui permettent respectivement d initialiser un sémaphore binaire et d appliquer les fonctions P et V à un sémaphore binaire. Struct sem_c int val ; // valeur du sémaphore. Init (sem_c S, int v0) P(sem_c S) V(sem_c S) Struct sem_c int val ; // valeur courante du sémaphore int nbwait ; // nombre de processus/threads en attente du sémaphore sem_b mutex; // pour protéger les sections critiques de P et V sem_b swait; // pour bloquer des processus/threads (les mettre en attente de S) Init (sem_c S, int v0) S.val=v0 ; S.nbwait= 0 ; initb(s.mutex,1) ; initb(s.swait,0) ; P(sem_c S) Pb(S.mutex) ; if (S.val >0) S.val-- ; Vb(S.mutex) ; else S.nbwait++ ; Vb(S.mutex) ; Pb(S.swait) ; V(sem_c S) Pb(S.mutex) ; if (S.nbwait >0) S.nbwait--; V(S.swait); else S.val++; Vb(S.mutex) ; Page 7 sur 7