Gestion de processus Corrigé TD 1 EFREI I

Slides:



Advertisements
Présentations similaires
Module Systèmes d’exploitation
Advertisements

Module Systèmes d’exploitation
Module Systèmes d’exploitation
Module Systèmes d’exploitation
Synchronisation de Processus
Chapitre annexe. Récursivité
Portée des variables VBA & Excel
Synchronisation des processus père - fils
Module Systèmes d’exploitation
Module Systèmes dexploitation Chapitre 6 Communication Interprocessus Partie III École Normale Supérieure Tétouan Département Informatique
GEF 435 Principes des systèmes d’exploitation
GEF 435 Principes des systèmes dexploitation Communication Interprocessus (CIP) II (Tanenbaum 2.3)
GEF 435 Principes des systèmes d’exploitation
GEF 435 Principes des systèmes d’exploitation
GEF 435 Principes des systèmes d’exploitation
GEF 243B Programmation informatique appliquée
TP 7.1 synchronized et join Écrire un programme Java qui crée 1000 threads et maintient un compteur nb du nombre de threads créés jusque-là. Le thread.
Synchronisation des Processus
1 UMLV 1. Introduction 2. Hachage ouvert 3. Hachage fermé 4. Implémentation des fonctions Méthodes de hachage.
Conception et programmation Programmation Parallèle
Chapitre 3 Coopération et synchronisation par variables partagées
Chapitre 3 Interblocages
Exécutif Temps réel. Limitation des système classiques Rappels Mise en œuvre lourde des communications entre processus Problème de prédictibilité avec.
C.
Présentation Création
Tableaux Certains problèmes nécessitent beaucoup de variables du même type. Exemple : relevé de températures matin et soir dans 10 villes pour 10 jours.
Ordonnancement du CPU Concepts de Base Critères d’Ordonnancement
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Récursivité.
Rappel sur la synchronisation des processus
Synchronisation et communication entre processus
La fonction alloue un bloc de taille size. Il faut indiquer la taille du bloc que lon veut allouer. Le premier exemple: #include void main()
Approche mémoire partagée Threads – Paradigme de lapproche – Objets exécutés par les processeurs threads vs processus, – un thread possède : Ses registres,
1 Les pointeurs et quelques rappels sur certains éléments du langage C.
Interblocage = impasse (Deadlock)
Complément Le diagramme des classes
5.1 URDL22005 Systèmes dexploitation Threads Vue dEnsemble Modèles de Multithreading Problèmes des Threads Pthreads Threads Windows XP Threads Linux Threads.
Algorithme de Bellman-Ford
8.1 URDL22005 Systèmes dexploitation Interblocages Modèle Système Caractérisation dinterblocage Méthodes pour Gérer les Interblocages Prévention des Interblocages.
Module 51 Module 5 - Synchronisation de Processus (ou threads, ou fils ou tâches) Module 5 - Synchronisation de Processus (ou threads, ou fils ou tâches)
Programmation concurrente
CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.
Chapitre 6 (Silberchatz)
Communication interprocessus
Chapitre 3 Interblocages 3.1. Ressources
Programme de baccalauréat en informatique Programmation Orientée Objets IFT Thierry EUDE Module 6. Gestion des erreurs et des exceptions : Fonctionnement.
Chapitre 6 : Synchronisation des processus et des fils
Synchronisation Classique
Synchronisation de Processus
Systèmes d’exploitation
Exemple de gestion d'un buffer clavier en liste circulaire
Ch. PAUL - Piles et Files à l'aide de listes chainées
Gérer la sécurité des mots de passe et les ressources
LES PILES ET FILES.
SYSTÈME D’EXPLOITATION I
Travailler avec des processus
Chapitre 6.2 Les curseurs Cours SGBD 3A Mme hkimi Jihène
NOTIONS DE BASE DES SYSTÈMES TEMPS-RÉEL Sujets Concepts de processus/thread concurrents –Windows NT et la programmation temps réel Lectures: Chapitres.
Interactions entre Processus
Programmation Système et Réseau
Cours LCS N°4 Présenté par Mr: LALLALI
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Introduction au langage C : Structures de contrôle 1 ère année Génie Informatique Dr Daouda Traoré Université de Ségou
Processus Légers. Rappel sur le fork() fork() Processus 1 Pile Data Text Processus 2 Pile Data Text.
Pthread Ordonnancement. #define _MULTI_THREADED #include #ifndef _CHECK_H #define _CHECK_H /* headers used by a majority of the example program */ #include.
Systèmes d’exploitation Processus conclusion Modèle conceptuel de processus Pour masquer les effets des interruptions, les SE fournissent un modèle conceptuel.
Interblocage = impasse (Deadlock)
Capocasale & Droz. Exécuter une fonction en parallèle Utilisation de plusieurs fonctions en parallèles pour obtenir un résultat Accès à des ressources.
1 UNIX AVANCE Yves PAGNOTTE – Janvier – LES PROCESSUS SOUS UNIX.
1 UNIX AVANCE Yves PAGNOTTE – Janvier – PROCESSUS ET RESSOURCES.
Transcription de la présentation:

Gestion de processus Corrigé TD 1 EFREI I1 2003 - 2004 Systèmes d'Exploitation 2003 - 2004 Corrigé TD 1 Gestion de processus 1- Threads, mutexes et variables de conditions #include <pthread.h> #include <stdio.h> #define NUM_THREADS 3 #define TCOMPTEUR 10 #define COMPTEUR_LIMIT 12 int compteur = 0; int thread_ids[3] = {0,1,2}; pthread_mutex_t compteur_mutex; pthread_cond_t compteur_threshold_cv;

void *inc_compteur(void *idp) { int j,i; double result=0.0; int *my_id = idp; for (i=0; i < TCOMPTEUR; i++) { pthread_mutex_lock(&compteur_mutex); compteur++; /* Vérifier la valeur du compteur et la thread en attente de signal quand la condition est réalisée. A noter que cela se produit pendant que le mutex est verrouillé. */ if (compteur == COMPTEUR_LIMIT) { pthread_cond_signal(&compteur_threshold_cv); printf("inc_compteur(): thread %d, compteur = %d Threshold reached.\n", *my_id, compteur); } printf("inc_compteur(): thread %d, compteur = %d, unlocking mutex\n", pthread_mutex_unlock(&compteur_mutex); /* faire un travail pour que les threads puissent alterner sur le verrouillage du mutex */ for (j=0; j < 1000; j++) result = result + (double)random(); pthread_exit(NULL);

void *watch_compteur(void *idp) { int *my_id = idp; printf("Starting watch_compteur(): thread %d\n", *my_id); /* Verrouiller mutex et attendre signal. A noter que la routine pthread_cond_wait() déverrouille mutex d'une manière automatique et atomique quand elle est en attente. A noter aussi, que si COMPTEUR_LIMIT est atteint avant que cette routine ne soit exécutée par la thread en attente, la boucle ne sera pas exécutée pour empêcher pthread_cond_wait() de ne jamais retourner. */ pthread_mutex_lock(&compteur_mutex); while (compteur < COMPTEUR_LIMIT) { pthread_cond_wait(&compteur_threshold_cv, &compteur_mutex); printf("watch_compteur(): thread %d Condition signal received.\n", *my_id); } pthread_mutex_unlock(&compteur_mutex); pthread_exit(NULL); void main() int i, rc; pthread_t threads[3]; pthread_attr_t attr;

/* Initialiser mutex et les variables de conditions */ pthread_mutex_init(&compteur_mutex, NULL); pthread_cond_init (&compteur_threshold_cv, NULL); /* Pour des raisons de portabilité, il faut explicitement créer les threads dans l'état " undetached" pour pouvoir les joindre (join) plus tard. */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED); pthread_create(&threads[0], &attr, inc_compteur, (void *)&thread_ids[0]); pthread_create(&threads[1], &attr, inc_compteur, (void *)&thread_ids[1]); pthread_create(&threads[2], &attr, watch_compteur, (void *)&thread_ids[2]); /* Attente pour la terminaison de toutes les threads */ for (i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } printf ("Main(): Waited on %d threads. Done.\n", NUM_THREADS); /* Nettoyer et quitter */ pthread_attr_destroy(&attr); pthread_mutex_destroy(&compteur_mutex); pthread_cond_destroy(&compteur_threshold_cv); pthread_exit (NULL);

2 - Ordonnancement a - Diagramme de temps FIFO 1 2 3 4 5 RR SJF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 FIFO 1 2 3 4 5 RR 1 2 3 4 5 1 3 5 1 5 1 5 1 5 1 1 1 1 1 SJF 2 4 3 5 1 Prio 4 1 3 5 2

b,c - Turnaround time - waiting time FCFS Round Robin SJF Prio Tâche b c b c b c b c 1 10 0 19 9 19 9 11 1 2 11 10 2 1 1 0 19 18 3 13 11 7 5 4 2 13 11 4 14 13 4 3 2 1 1 0 5 19 14 14 9 9 4 18 13 Moy 13.4 9.6 9.2 5.4 7.0 3.2 12.4 8.6 d - Avec SJF on a le temps d ’attente moyen minimal. Cependant, l ’implémentation de SJF est très difficile. En outre, comme tous les algorithmes d ’ordonnancement à priorités, SJF peut mener à un problème de famine.

3- Algorithme de Peterson pour 2 processus boolean drapeau[2]; int tour; drapeau[0] = false; drapeau[1] = false; void P0() { while(true) drapeau[0] = true; tour = 1; while (drapeau[1] && tour == 1) /* ne rien faire */; /* section critique */; drapeau[0] = false; /* section non critique */; } void P1() { while(true) drapeau[1] = true; tour = 0; while (drapeau[0] && tour == 0) /* ne rien faire */; /* section critique */; drapeau[1] = false; /* section non critique */; }

Algorithme de Peterson (suite) Considérons le processus P0 : une fois drapeau[0] = true, P1 ne peut pas entrer dans la section critique. Si P1 est déjà dans la section critique, alors drapeau[1] = true, P0 est bloqué et ne pourra pas entrer en section critique. D'autre part, il n'y a pas de blocage mutuel. Supposons P0 bloqué dans la boucle while. Cela veut dire que drapeau[1]=true et tour=1. P0 peut entrer dans la section critique quand drapeau[1] = false ou tour = 0. Considérons les 3 cas suivants: - P1 ne veut pas entrer dans la section critique. Ceci est impossible car cela impliquerait drapeau[1] = false - P1 est en attente pour entrer en section critique. Ce cas est impossible parce que si tour = 1, P1 peut entrer dans la section critique - P1 utilise la section critique souvent et monopolise l'accès à cette section. cela ne pourra pas se produire car P1 est obligé de donner une chance à P0 en mettant tour = 0 avant chaque essai d'entrer dans sa section critique.

4 - Synchronisation de processus avec des sémaphores Producteur - consommateur a – mutex gère un accès en exclusion mutuelle, sa valeur initiale est donc 1 plein compte les places occupées, sa valeur initiale est donc 0. vide compte les places inoccupées, sa valeur initiale est donc n. b – Processus producteur debut tant que vrai faire produire un element elt ; wait (vide) ; wait (mutex) ; ajouter elt dans le tampon ; signal (mutex) ; signal (plein) ; fin c – Processus consommateur debut tant que vrai faire wait (plein) ; wait (mutex) ; retirer elt du tampon ; signal (mutex) ; signal (vide) ; consommer elt ; fin

5 - Détection d'interblocage (deadlock detection) Détection et reprise : Le système ne cherche pas à empêcher les interblocages. Les ressources demandées sont allouées quand elles sont disponibles. La détection de l ’interblocage(attente circulaire) est faite périodiquement à postériori ou à chaque allocation, ce qui consomme beaucoup de temps processeur. a - Détection avec une seule ressource d’un type donné : Construire le graphe des ressources. Si le graphe contient un ou plusieurs cycles, il y a interblocage. S’il n 'y a pas de cycles, Il n’y a pas d’interblocage. b - Détection avec plusieurs exemplaires d’une même ressource : L’algorithme fait appel à une matrice pour détecter l'interblocage de m processus. Définissons les vecteurs et les matrices suivants : e = (e1, e2, ..., en) : ensemble de ressources disponibles (non allouées à un processus) t = r = Chaque rangée de la matrice r indique les besoins d’un processus, i.e, rij indique les besoins du processus i pour la ressource j. L’algorithme marque les processus qui ne sont pas en interblocage. Initialement, aucun processus n’est marqué. Ensuite, on fait les étapes suivantes : 1- marquer chaque processus qui a une rangée de zéros dans la matrice d’allocation t. 2- initialiser un vecteur temporaire W égal au vecteur des ressources disponibles. 3- trouver un indice i tel qu ’aucun processus i n’est marqué et que rik <= Wk pour 1 <= k <= n. Si aucune rangée n’existe, alors terminer l’algorithme. 4- si une telle rangée existe, marquer le processus i et ajouter la rangée correspondante de la matrice des ressources allouées t à W. Wk = Wk + tik. Aller à l ’étape 3. t11 t12 … t1n t21 t22 … t2n … … … … tm1 tm2 … tmn Matrice des ressources allouées r11 r12 … r1n r21 r22 … r2n … … … … rm1 rm2 … rmn Matrice des requêtes

Vecteur des ressources Vecteur des ressources disponibles Voici un exemple d’illustration de cet algorithme : R1 R2 R 3 R4 R5 R1 R2 R 3 R4 R5 P1 P2 P3 P4 0 1 0 0 1 P1 P2 P3 P4 1 0 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 Matrice des requêtes Matrice d’allocation R1 R2 R 3 R4 R5 Vecteur des ressources 2 1 1 2 1 R1 R2 R 3 R4 R5 Vecteur des ressources disponibles 0 0 0 0 1 Déroulement de l ’algorithme : 1- marquer P1 car P1 ne possède pas de ressources allouées 2- W = ( 0 0 0 0 1) 3- la requête de P3 est inférieure ou égale à W, alors marquer P3 et faire W = W + ( 0 0 0 1 0 ) = ( 0 0 0 11 ) 4- terminer l’algorithme P1 et P2 ne sont pas marqués, ce qui indique qu’ils sont en interblocage.

On suppose que dans les matrices, le numéro de ligne désigne le processus et le numéro de colonne le type de ressource. int executable (int m, int n, int *dispo, int **requete, int *exec); int interblocage (int m, int n, int *existe, int **tenu, int **requete) { int *dispo = malloc (n*sizeof (int)), *exec = malloc (m*sizeof (int)), i, j, k; /* Calcul des ressources disponibles */ for ( j = 0; j < n; j++) { dispo[j] = existe[j]; for ( i = 0; i < m; i++) dispo[j] -= tenu[i][j]; } /* exec sert à marquer les processus exécutés */ for (i = 0; i < m; i++) exec[i] = 0; for (i = 0; i < m; i++) { j = executable(m, n, dispo, requete, exec); if (j < 0) return 1; /* interblocage */ /* Rendre les ressources allouées à ce processus */ for (k = 0; k < n; k++) dispo[k] += tenu[j][k]; exec[j] = 1; /* tous les processus ont été exécutés, pas d ’interblocage */ return 0;

/* Retourne le numéro du premier processus exécutable (et non exécuté) -1 s ’il n ’en existe pas.*/ int executable (int m, int n, int *dispo, int **requete, int *exec) { int i, j; for (i = 0; i < m; i++) if (!exec[i]) { for (j = 0; j < n; j++) if (requete[i][j] > dispo[j]) break; if (j >= n) return i; } return -1; - La complexité de la fonction executable est comprise entre n (si le premier processus est exécutable) et mn (si c ’est le dernier); donc la complexité de la fonction interblocage est comprise entre mn et m2n.

6- Evitement de l'interblocage (Deadlock Avoidance) a- Cet état est sain avec la séquence {P2,P1,P3,P4} b- Cet état n'est pas sain parce que chaque processus a besoin d'un exemplaire supplémentaire de R1. La requête est refusée et le processus P1 est bloqué.

Exercices supplémentaires 1 - 2 - 3 - 4 - 5 -