CONSERVATOIRE NATIONAL DES ARTS ET METIERS



Documents pareils
Cours Programmation Système

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

Cours 6 : Tubes anonymes et nommés

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

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

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

Systèmes d Exploitation - ENSIN6U3. Aix-Marseille Université

Cours de Systèmes d Exploitation

Partie 7 : Gestion de la mémoire

INTRODUCTION À LA PROGRAMMATION CONCURRENTE

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

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

Chapitre 4 : Outils de communication centralisés entre processus

Gestion des processus

SGM. Master S.T.S. mention informatique, première année. Isabelle Puaut. Septembre Université de Rennes I - IRISA

REALISATION d'un. ORDONNANCEUR à ECHEANCES

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

Concept de machine virtuelle

Problèmes liés à la concurrence

Systemes d'exploitation des ordinateurs

Introduction aux Systèmes et aux Réseaux

Chapitre V : La gestion de la mémoire. Hiérarchie de mémoires Objectifs Méthodes d'allocation Simulation de mémoire virtuelle Le mapping

Introduction à la programmation concurrente

Programmation C++ (débutant)/instructions for, while et do...while

Projet gestion d'objets dupliqués

<Insert Picture Here> Solaris pour la base de donnés Oracle

Un ordonnanceur stupide

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

ENSP Strasbourg (Edition ) Les Systèmes Temps Réels - Ch. DOIGNON. Chapitre 3. Mise en œuvre : signaux, gestion du temps et multi-activités

Les avantages de la virtualisation sont multiples. On peut citer:

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

Le prototype de la fonction main()

Programmation Système (en C sous linux) Rémy Malgouyres LIMOS UMR 6158, IUT département info Université Clermont 1, B.P.

Introduction au langage C

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


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

Qu'est-ce qu'un processus: Définitions

Programmation système

4. Outils pour la synchronisation F. Boyer, Laboratoire Lig

Derrière toi Une machine virtuelle!

Informatique industrielle A Systèmes temps-réel J.F.Peyre. Partie I : Introduction

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

I. Introduction aux fonctions : les fonctions standards

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

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

Initiation à la sécurité

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Programmation système en C/C++

SYSTÈME DE GESTION DE FICHIERS

Gestion de la mémoire

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

Le modèle de sécurité windows

Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

SYSTÈME DE GESTION DE FICHIERS SGF - DISQUE

Les processus. Système L3, /39

Programmation système de commandes en C

Projet de Veille Technologique

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

Corrigé des TD 1 à 5

GESTION DE LA MEMOIRE

Méthodes de programmation systèmes UE n NSY103. Notes de cours. Nombre d'heures : 55h (~ cours de 3 heures)

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

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

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Systèmes d exploitation Gestion de processus

Communication Interprocessus

UE C avancé cours 1: introduction et révisions

TD2/TME2 : Ordonnanceur et Threads (POSIX et fair)

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

Threads. Threads. USTL routier 1

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

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)

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

INF4420: Éléments de Sécurité Informatique

Gestion des transactions et accès concurrents dans les bases de données relationnelles

V- Manipulations de nombres en binaire

Linux embarqué Retour d expérience et temps réel. Denis Coupvent-Desgraviers

Introduction à la Programmation Parallèle: MPI

Gestion répartie de données - 1

Application 1- VBA : Test de comportements d'investissements

Dossier projet isn 2015 par Victor Gregoire

Performances de la programmation multi-thread

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Génie Logiciel avec Ada. 4 février 2013

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

Java Licence Professionnelle CISII,

Programmer en JAVA. par Tama

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Chapitre 2 Devine mon nombre!

SafeGuard Enterprise Guide des outils. Version du produit : 5.60

Algorithmique I. Algorithmique I p.1/??

KoinKoin. Système d exploitation à architecture basée micro-noyau. Antoine Castaing Nicolas Clermont Damien Laniel

Chapitre 1 : Introduction aux bases de données

//////////////////////////////////////////////////////////////////// Administration bases de données

Communications performantes par passage de message entre machines virtuelles co-hébergées

Année Universitaire 2009/2010 Session 2 de Printemps

Etude de l ENT de l Université de Paris 5. Mise en place d outils de suivi de la charge de l ENT (monitoring)

Transcription:

CONSERVATOIRE NATIONAL DES ARTS ET METIERS Durée : 2 heures METHODES DE PROGRAMMATION SYSTEMES UE NSY103 - NANCY/METZ INTERVENANT : E. DESVIGNE CORRECTION DE LA SESSION DE RATTRAPAGE 13/09/2011 Année 2010 2011, deuxième semestre Coefficient : 1/1 (compte pour la totalité de la note) Documents autorisés : NON

Exercice n 1 : jeu de la patate chaude (3 questions pour un total de 8 pos) Question 1.a) [1 po] : dans un environnement Unix/Linux, un «processus» est un programme dont l'exécution se déroule en partageant le (ou les) CPU avec d'autres processus. Les processus sont «isolés» les uns des autres (chaque processus a sa propre zone mémoire, ses propres descripteurs de fichiers, etc.). Question 1.b) [1 po] : un pipe anonyme est un canal de communication FIFO qui permet la connunication d'un flux de données entre un père et son fils (ou vice et vers ça). Le pipe est créé par le père, et les descripteurs de fichiers sont hérités par le fils. Les pipes nommés fonctionnent suivant le même principe, mais peuvent être utilisés par deux processus sans lien de parenté direct. Les descripteurs de fichiers font alors référence à un nom de fichier (de type "pipe"). Question 1.c) [6 pos] : <stdio.h> <stdlib.h> <unistd.h> <signal.h> <sys/types.h> <sys/wait.h> tab_pid[4]; // contiendra le PID de chaque joueur p[4][2]; // les 4 pipes anonymes score; // le score du processus nb_joueur; num_joueur_aleat() long li; li=lrand48()%4; return(()li); void reception_patate_fils() prochain_joueur; signal(sigusr1, reception_patate_fils); // on réarme score++; if (score < 1000) // on retire un nombre aleatoire tant qu'on se choisit nous même do prochain_joueur=num_joueur_aleat(); while (prochain_joueur==nb_joueur); kill(tab_pid[prochain_joueur], SIGUSR1); else // fin de partie, on envoie la patate au père kill(getppid(), SIGUSR1); void reception_patate_pere() // quand le père reçoit la patate, il envoie le signal SIGUSR2 aux 4 // fils, puis il récupère leur valeur de fin pour éviter les zombies, // puis s'en va... i; kill(tab_pid[i], SIGUSR2); // on récupère les valeurs de exit() des fils pour éviter les zombies... Correction session de rattrapage NSY103, 2ème semestre 2010-2011, 2 heures Page 2/7

wait(null); exit(0); void recoit_fin_partie() prf("joueur %d, score : %d\n", nb_joueur, score); exit(0); main() i, j; // Création de 4 pipes anonymes pipe(p[i]); // initialisation du score pour tous score=0; // Création des 4 joueurs nb_joueur=0; while ( (nb_joueur<4) && ((tab_pid[nb_joueur]=fork())>0) ) nb_joueur++; if (nb_joueur==4) // on a reçu 4x un nbre >0 au fork() => on est le père signal(sigusr1, reception_patate_pere); // on ferme les pipes en réception : close(p[i][0]); // pour chacun des 4 fils, on envoie les 4 PID for (j=0 ; j<4 ; j++) write(p[i][1], &(tab_pid[j]), sizeof(tab_pid[j])); // on ferme les pipes d'émission close(p[i][1]); // on envoie la patate ;-) i=num_joueur_aleat(); kill(tab_pid[i], SIGUSR1); for (;;) ; else // code des fils (NB: chaque fils est le joueur nb_joueur) signal(sigusr1, reception_patate_fils); signal(sigusr2, recoit_fin_partie); // on ferme les pipes d'émission close(p[i][1]); // on reçoit les pid des joueurs read(p[nb_joueur][0], &(tab_pid[i]), sizeof(tab_pid[i])); // on ferme les pipes de réception : close(p[i][0]); for (;;) ; Correction session de rattrapage NSY103, 2ème semestre 2010-2011, 2 heures Page 3/7

Exercice n 2 : mémoire, segmentation, pagination (3 questions pour un total de 6 pos) Question 2.a) [1 po] : La pagination. Question 2.b) [2 pos] : La MMU ne pouvant charger toute la table des pages en mémoire, les fondeurs ont mis en place la pagination multiniveaux (ou hyperpagination), avec la notion d'hypertable. L adresse virtuelle ne contient plus deux sous ensembles (la page et le décalage), mais 3 : l hyperpage, la page, et le décalage. L accès à la mémoire physique se fait alors avec un accès supplémentaire : la lecture de l hyperpage est utilisée comme entrée dans l hypertable, et nous permet d accéder à une table des pages ; la page permet de trouver le cadre dans la table des pages ainsi obtenue ; la lecture de la donnée dans la mémoire physique se fait à l aide de ce cadre et du décalage. Schéma de la traduction d'une telle adresse : N hyperpage Adresse logique N de page Déplacement Hypertable des pages N hyperpagetable pages Table des pages N de page N de cadre...... Numéro de cadre Déplacement Adresse physique Traduction d adresse (hyperpagination) Question 2.c) [3 pos] : L algorithme LRU (Least Recently Used/la moins récemment utilisée) consiste à choisir comme victime la page qui n'a pas été référencée depuis le plus longtemps. Page demandée 5 6 7 0 6 1 6 2 0 1 5 1 0 7 0 6 7 5 6 0 Case 0 5 5 5 0 0 0 0 2 2 2 5 5 5 7 7 7 7 7 7 0 Case 1 6 6 6 6 6 6 6 6 1 1 1 1 1 1 6 6 6 6 6 Case 2 7 7 7 1 1 1 0 0 0 0 0 0 0 0 0 5 5 5 Défaut de page A la fin de tous les accès, la table des pages est alors : page bit V case 0 1 0 1 0 / 2 0 / 3 0 / 4 0 / 5 1 2 6 1 1 7 0 / O N O N O O O O N N O N O N O N O Correction session de rattrapage NSY103, 2ème semestre 2010-2011, 2 heures Page 4/7

Remarque du correcteur : noter juste ce tableau même si le tableau précédent est faux, du moment ou le candidat sait retrouver cette table des pages à partir de la table des cases à laquelle il a abouti. Exercice n 3 : les threads (3 questions pour un total de 6 pos) Question 3.a) [1,5 po] : Le concept de thread permet d'effectuer de la multiprogrammation (plusieurs programmes se partagent le temps CPU), au même titre que les processus. Seulement, les processus souffrent de trois défauts majeurs : la création d'un nouveau processus (avec la création d'un nouveau PCB, la mise en œuvre de segments de mémoire isolés, etc.) est coûteuse, même si le «copy on write» permet d'alléger ce mécanisme ; le fait que deux processus aient deux espaces mémoire isolés rend la commutation de contexte coûteuse ; et pour la même raison (espaces mémoire isolés), les mécanismes de communication er-processus sont eux aussi coûteux (recopie d'information par exemple). Or, parfois, les programmeurs ont besoin de faire de la multiprogrammation, sans qu'il soit nécessaire (bien au contraire) que les deux tâches aient des espaces mémoire isolés. Les threads (ou processus légers) ont été inventés dans ce but : proposer un mécanisme qui permet de créer plusieurs tâches au sein d'un même processus. Ces tâches partagent le même code et les mêmes données (tas, variables globales, constantes, etc.). Seule la pile à l'exécution et l'état des registres sont spécifiques à chaque thread. Question 3.b) [1,5 po] : Il existe deux types de thread : les threads utilisateur et les threads noyau. Les threads utilisateurs sont implémentés dans une bibliothèque de fonctions qui s'exécutent en mode utilisateur. Le système d'exploitation (et en particulier l'ordonnanceur) n'a pas connaissance de la notion de thread. L'ordonnancement des différentes tâches des différents threads est assurée par un ordonanceur spécifique, qui s'exécute dans le processus en mode utilisateur (sans privilège système). Les threads noyaux sont implémentés dans le système d'exploitation. L'ordonnanceur du système d'exploitation doit connaître la notion de thread, et doit gérer lui-même l'ordonnancement des tâches des différents threads au sein d'un processus. Avantages des threads utilisateurs : ils permettent, dans les anciens systèmes d'exploitation, de proposer aux programmeurs le mécanisme de thread même quand le système d'exploitation ne proposait pas ce concept ; souvent, la bibliothèque de fonctions qui assure l'ordonancement des différents threads au sein d'un processus ne nécessite pas un coûteux passage en mode "privilégié". Leur inconvénient : si un thread effectue un appel système bloquant, ce sont tous les threads du processus qui se retrouvent bloqués. Question 3.c) [3 pos] : Tout d'abord, le programmeur utilise les mutex Mut1 et Mut2 pour protéger l'accès à des variables locales. Or, ces variables sont stockées dans la pile à l'exécution. Sachant que chaque thread possède sa propre pile à l'exécution, ces variables ne sont pas partagées. D'ailleurs, le compilateur fournira une erreur " variables compteur_commun1 et compteur_commun2 inconues dans la fonction second_thread() ". La solution : ressortir les déclarations de ces deux variables dans le corps du programme, en dehors de toute fonction, afin que ces variables soient globales. Elles seront alors connues de toutes les fonctions, et leurs valeurs sera partagée entre les deux threads (d'où l'érêt de les protéger par des mutex). Correction session de rattrapage NSY103, 2ème semestre 2010-2011, 2 heures Page 5/7

Ensuite, un des threads positionne un verrou Mut1 avant de verrouiller Mut2. Inversement, le second thread verrouille Mut2 avant Mut1. Il peut donc y avoir erblocage, ou étree mortelle entre les deux threads (s'il y a préemption d'un tread entre deux verrouillages, et que l'autre thread positionne ses deux verrous). Dans le cas présent, comme il n'y a que deux threads et deux ressources à protéger, la solution est simple : il suffit de toujours verrouiller les mutex dans le même ordre (par exemple en ervertissant les lignes " pthread_mutex_lock(&mut2); " et " pthread_mutex_lock(&mut1); " dans la fonction second_thread(). Le code correct est le suivant (modifications en rouge) : <stdio.h> <stdlib.h> <unistd.h> <pthread.h> extern void gros_calcul(); extern void petit_calcul(); extern void modifie_compteurs( *, *); extern on_continue(); pthread_mutex_t pthread_mutex_t Mut1=PTHREAD_MUTEX_INITIALIZER; Mut2=PTHREAD_MUTEX_INITIALIZER; /* Variables globales (donc, visibles par tous les threads) */ compteur_commun1 = 0; compteur_commun2 = 0; void *second_thread() while (on_continue(compteur_commun1)) gros_calcul(); /* les mutex sont employés dans le même ordre : */ pthread_mutex_lock(&mut1); pthread_mutex_lock(&mut2); modifie_compteurs(&compteur_commun1, &compteur_commun2); pthread_mutex_unlock(&mut2); pthread_mutex_unlock(&mut1); pthread_exit(null); return(null); main() pthread_t th; /* les lignes ci-dessous ont été mises en commentaire */ /* compteur_commun1 = 0; */ /* compteur_commun2 = 0; */ /* On crée le second thread */ if ((pthread_create(&th, NULL, second_thread, NULL))!=0) fprf(stderr, "Erreur pthread_create()\n"); exit(-1); Correction session de rattrapage NSY103, 2ème semestre 2010-2011, 2 heures Page 6/7

while (on_continue(compteur_commun1)) pthread_mutex_lock(&mut1); pthread_mutex_lock(&mut2); modifie_compteurs(&compteur_commun1, &compteur_commun2); pthread_mutex_unlock(&mut2); pthread_mutex_unlock(&mut1); petit_calcul(); pthread_mutex_lock(&mut1); compteur_commun1++; pthread_mutex_unlock(&mut1); pthread_join(th, NULL); pthread_mutex_destroy(&mut1); pthread_mutex_destroy(&mut2); return(0); /* Fin du programme */ Correction session de rattrapage NSY103, 2ème semestre 2010-2011, 2 heures Page 7/7