ED 1 : Synchronisation à l aide des sémaphores et des moniteurs Posix

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

Problèmes liés à la concurrence

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

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

Cours de Systèmes d Exploitation

INTRODUCTION À LA PROGRAMMATION CONCURRENTE

Introduction à la programmation concurrente

Les structures. Chapitre 3

Exécutif temps réel Pierre-Yves Duval (cppm)

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

DAns un système d exploitation multiprogrammé en temps partagé, plusieurs

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

Le langage C. Séance n 4

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

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

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

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

Examen d informatique première session 2004

V- Manipulations de nombres en binaire

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

Chapitre 4 : Exclusion mutuelle

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

OS Réseaux et Programmation Système - C5

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Le prototype de la fonction main()

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)

TD2 Programmation concurrentielle

Introduction aux systèmes temps réel. Iulian Ober IRIT

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

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

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Introduction à la Programmation Parallèle: MPI

Cours Programmation Système

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

TP Temps Réel. Polytech Paris - Mars 2012

Noyau de concurrence par moniteur pour Java ou C# pour une autre sémantique plus fiable et plus performante

Initiation. àl algorithmique et à la programmation. en C

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

Souad EL Bernoussi. Groupe d Analyse Numérique et Optimisation Rabat http ://

Chapitre 1 : La gestion dynamique de la mémoire

Programmation système I Les entrées/sorties

Un ordonnanceur stupide

Sixième partie. Programmation multi-activités Java & Posix Threads. Généralités Java Threads POSIX Threads Autres approches

Derrière toi Une machine virtuelle!

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

J2SE Threads, 1ère partie Principe Cycle de vie Création Synchronisation

REALISATION d'un. ORDONNANCEUR à ECHEANCES

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

Introduction au langage C

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

Les structures de données. Rajae El Ouazzani

Algorithmique et Programmation, IMA

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

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence

1.6- Génération de nombres aléatoires

Programme Compte bancaire (code)

Eclipse atelier Java

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

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

PIC EVAL Dev Board PIC18F97J60

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Introduction au pricing d option en finance

Exo7. Calculs de déterminants. Fiche corrigée par Arnaud Bodin. Exercice 1 Calculer les déterminants des matrices suivantes : Exercice 2.

TP1 : Initiation à Java et Eclipse

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

Ordonnancement temps réel

Quelques éléments de compilation en C et makefiles

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

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

Premiers Pas en Programmation Objet : les Classes et les Objets

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

Introduction : les processus. Introduction : les threads. Plan

Chapitre 2. Classes et objets

Déroulement. Evaluation. Préambule. Définition. Définition. Algorithmes et structures de données 28/09/2009

Définition 0,752 = 0,7 + 0,05 + 0,002 SYSTÈMES DE NUMÉRATION POSITIONNELS =

On appelle variable condition une var qui peut être testée et

Compression de Données - Algorithme de Huffman Document de Conception

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

#include <stdio.h> #include <stdlib.h> struct cell { int clef; struct cell *suiv; };

Chap 4: Analyse syntaxique. Prof. M.D. RAHMANI Compilation SMI- S5 2013/14 1

Systèmes temps-réel. Plan général. Matthieu Herrb. Mars Introduction - concepts généraux

Programmation système

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

Chapitre 4 : Outils de communication centralisés entre processus

Mon premier rpm. 7 juin Avant de commencer RPM URPMI RPMBUILD... 2

L exclusion mutuelle distribuée

Comment devenir éditeur de logiciels libres quand on est une entreprise?

CHAPITRE VIII : Les circuits avec résistances ohmiques

Algorithmique I. Algorithmique I p.1/??

Cours d initiation à la programmation en C++ Johann Cuenin

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

Les fichiers. Chapitre 4

Développement d un logiciel de messagerie instantanée avec Dotnet (version simplifiée)

Utilisation d objets : String et ArrayList

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

as Architecture des Systèmes d Information

Projet de programmation (IK3) : TP n 1 Correction

CAISSE ENREGISTREUSE ELECTRONIQUE SE-G1

Transcription:

ED 1 : Synchronisation à l aide des sémaphores et des moniteurs Posix Samia Bouzefrane Laboratoire CEDRIC Conservatoire National des Arts et Métiers http://cedric.cnam.fr/~bouzefra 1

Partie I : Problème des philosophes Le paradigme des philosophes et des spaghettis a été posé la première fois par Dijkstra en 1971. Cinq philosophes sont réunis autour d'une table pour philosopher. Mais comme leur réflexion intense nécessite une alimentation en rapport, on a disposé un grand plat de spaghetti au milieu de la table et une assiette et une fourchette devant chaque philosophe. Ces philosophes respectent rigoureusement un rituel qui impose de manger les spaghettis avec deux fourchettes et non avec une seule. Il aurait donc fallu déposer sur la table 10 fourchettes et non 5. Il y a là un problème de partage de ressources (les fourchettes) et les philosophes conviennent du protocole suivant: après une période de réflexion, un philosophe qui désire manger ne peut le faire que si les deux fourchettes, celle à sa gauche et celle à sa droite, les seules dont il peut se servir, sont toutes les deux libres. A un instant donné, seuls deux philosophes peuvent être en train de manger simultanément. Bien entendu, un philosophe qui mange s'arrête de manger au bout d'un temps fini. On peut assimiler chaque philosophe à un processus cyclique: Répéter Penser; Prologue; Manger section critique; Epilogue; Jusqua Faux; Une solution basée sur les sémaphores Posix serait la suivante : Question 1 : Quel est le problème qui peut se poser dans cette solution? Vérifiez-le en exécutant le programme correspondant sachant que la compilation et l exécution d un programme C se fait comme suit : $gcc Philo.c o Philo lpthread $./Philo Solution 1 /* PhiloSem.c avec des semaphores et des threads*/ #include <stdio.h> #include <semaphore.h> // declaration des semaphores // ligne 1: sem_t Fourchette[5]; void *Philosophe(void * t) int j; int i=(int) t; srand(pthread_self()); for(j=0; j<20; j++) printf("philosophe %d pense \n",i); sleep(rand()%3); printf("philosophe %d veut manger \n",i); // ligne 2 : sem_wait(&fourchette[i]); sem_wait(&fourchette[(i+1)%5]); 2

printf("philosophe %d est en train de manger avec Fourch %d et Fourch %d \n", i, i, (i + 1)%5); sleep(rand()%5); sem_post(&fourchette[i]); sem_post(&fourchette[(i+1)%5]); // ligne 3: printf("philosophe %d libere les fourchettes \n", i, i, (i+1)%5); pthread_exit (0); int main(void) pthread_t th[5]; int i; /* creation et initialisation des semaphores */ // ligne 4: for (i=0; i<5; i++) sem_init(&fourchette[i], 0, 1); /* creation des threads */ for (i=0; i<5; i++) pthread_create (&th[i], 0, (void *(*)())Philosophe,(void *)i); /* attente de terminaison */ for (i=0; i<5; i++) pthread_join (th[i], NULL); /* suppression des semaphores */ //ligne 5 for (i=0; i<5; i++) sem_destroy(&fourchette[i]); return (0); Question 2 : On complète le programme précédent avec les lignes suivantes : ligne 1 : sem_t Antichambre ; ligne 2 : sem_wait(&antichambre); ligne 3 : sem_post(&antichambre); ligne 4 : sem_init(&antichambre, 0, 4); ligne 5 : sem_destroy(&antichambre) ; A quoi servent ces lignes? Expliquez comment cela permet de résoudre le problème précédent. Vérifiez-le en exécutant le programme. Question 3 : Une solution du même problème qui utilise les moniteurs Posix, figure à l URL suivante : http://cedric.cnam.fr/~bouzefra/livre/chapitre8/philo.c. Quel est le problème qui peut se poser dans cette solution. Téléchargez ce programme et exécutez-le. 3

Partie II : Allocation de ressources Nous nous intéressons au problème d allocation de ressources banalisées. Nous supposons disposer dans un système de plusieurs exemplaires d une même ressource, dont un nombre quelconque peut être demandé par un processus à un moment donné. Pour simplifier, nous considérons un seul type de ressource. Tout processus actif qui demande des exemplaires de cette ressource, doit solliciter les services d un allocateur via deux procédures : - request(m) : pour demander l allocation de m exemplaires de la ressource - release(m) : pour libérer les m exemplaires de la ressource L allocateur maintient une variable critique qui compte le nombre d exemplaires disponibles afin de satisfaire éventuellement de nouvelles demandes. Contexte commun : entier NbRessDisponibles :=Max ; Comportement d un processus : While (true) request(m) ; utiliser les m ressources release(m) ; Procédure request (entier m) Tant que (NbRessDisponibles<m) bloquer le processus appelant ; NbRessDisponibles = NbRessDisponibles m ; // allocation des m ressources Procédure release(entier m) // libération des m ressources NbRessDisponibles = NbRessDisponibles +m ; Réveiller des processus qui seraient bloqués Notons que dans cette solution, plusieurs processus demandeurs peuvent être servis simultanément s il y a suffisamment de ressources. De plus, la procédure release doit réveiller tous les processus en attente pour trouver ceux pour lesquels les demandes peuvent être satisfaites. Question Complétez le programme C suivant qui utilise des moniteurs Posix. Notons qu il existe une primitive qui permet de réveiller tous les processus à la fois en attente derrière une condition : int pthread_cond_broadcast(pthread_cond_t *condition); Le programme obtenu doit être compilé avec l option -lpthread. /* allocation.c */ #include <stdio.h> #include <pthread.h> #define NbTh 5 ressources */ #define M 100 /*Nombre de threads symbolisant les demandeurs de 4

pthread_t tid[nbth]; pthread_mutex_t mutex; pthread_cond_t condressnondispo; // variable critique int NbRessDisponibles=M; void request(int m) // a completer void release(int m) // a completer void * Demandeur(void ) int j; srand(pthread_self()); j=rand()%100; request(j); /* temps d'utilisation */ printf("le demandeur %d utilise les ressources\n", pthread_self()); usleep(rand()%200000); release(j); int main() int num; // initialiser les mutex et conditions //creation des threads pthread_create(tid+num,0,(void *(*)())Demandeur,NULL ); //attend la fin de toutes les threads pthread_join(tid[num],null); // detruire les resources allouees return 0; 5

Solution Exercice 1 Question 1 : La solution telle qu elle est donnée peut présenter une situation d interblocage. Chaque philosophe i détient une fourchette i et demande la fourchette i+1 détenue par le philosophe i+1. Question 2 : La solution améliorée est une solution équitable et a été proposée par Ben Ari. Elle rajoute un sémaphore qui symbolise une antichambre par laquelle doivent passer les philosophes pour faire leur demande. Cette antichambre ne peut contenir au plus que 4 philosophes. Ce qui permet dans le pire cas d avoir au moins un philosophe parmi les cinq (s ils sont tous demandeurs) qui obtient les 2 fourchettes. Pas d interblocage dans cette solution, de plus grâce à l antichambre les demandeurs seront servis dans l ordre. Question 3 : La solution des philosophes basée sur les moniteurs ne présente pas de situation d interblocage mais peut générer de la famine parce que ce sont toujours les mêmes philosophes qui sont servis. Exercice 2 Question 2 /* allocation.c */ #include <stdio.h> #include <pthread.h> #define NbTh 5 ressources */ #define M 100 /*Nombre de threads symbolisant les demandeurs de pthread_t tid[nbth]; pthread_mutex_t mutex; pthread_cond_t condressnondispo; // variable critique int NbRessDisponibles=M; void request(int m) pthread_mutex_lock(&mutex); while(nbressdisponibles < m) pthread_cond_wait(&condressnondispo, &mutex); printf("le demandeur %d alloue %d ressources\n", pthread_self(),m); NbRessDisponibles = NbRessDisponibles - m; printf("le nb de ress disponibles %d \n", NbRessDisponibles); pthread_mutex_unlock(&mutex); void release(int m) pthread_mutex_lock(&mutex); printf("le demandeur %d libere %d ressources\n",pthread_self(),m); NbRessDisponibles = NbRessDisponibles + m; 6

printf("le nb de ress disponibles %d \n", NbRessDisponibles); pthread_cond_broadcast(&condressnondispo); pthread_mutex_unlock(&mutex); void * Demandeur(void ) int j; srand(pthread_self()); j=rand()%100; request(j); /* temps d'utilisation */ printf("le demandeur %d utilise les ressources\n", pthread_self()); usleep(rand()%200000); release(j); int main() int num; pthread_mutex_init(&mutex,0); pthread_cond_init(&condressnondispo,0); //creation des threads pthread_create(tid+num,0,(void *(*)())Demandeur,NULL ); //attend la fin de toutes les threads pthread_join(tid[num],null); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&condressnondispo); return 0; 7