********************************** TP 5 - Moniteurs et semaphores de comptage en pthread Partie 2 : Problème des lecteurs/redacteurs Duree: 3h ********************************** ********************************** Resolution du probleme des lecteurs redacteurs avec les pthreads - Partie 2.1: avec des semaphores de comptage uniquement - Partie 2.2: avec des semaphores mutex uniquement - Partie 2.3: avec des moniteurs uniquement ********************************** Contenu: * lecteurs-redacteurs-mutex.c : Le fichier d'implementation des lecteurs redacteurs pour semaphores mutex uniquement (ou semaphores de comptage) qui contient: lecteur() : fonction principale des threads lecteurs redacteurs () : fonction principale des threads redacteurs main() : fonction principale du processus (initialisation, demarrage/terminaison des threads, finalisation) * lecteurs-redacteurs-moniteur.c : Le fichier d'implementation des lecteurs redacteurs pour les moniteurs uniquement (mutex et conditions) qui contient: m_prologue_lecteur() et m_epilogue_lecteur(): les points d'entree du moniteur pour les lecteurs m_prologue_redacteur() et m_epilogue_redacteur(): les points d'entree du moniteur pour les redacteurs lecteur() : fonction principale des threads lecteurs redacteurs () : fonction principale des threads redacteurs main() : fonction principale du processus (initialisation, demarrage/terminaison des threads, finalisation) * semaphore-moniteur.h, semaphore-moniteur.c : Les fichiers d'implementation des semaphores de comptage avec les moniteurs pthreads (à utiliser dans la partie 2.1) type_semaphore ; init_semaphore(); destroy_semaphore(); P_semaphore(); V_semaphore(); * tprinf.h, tprinf.c : Les fichiers d'implementation d'un utilitaire tprinf() et tfprintf() printf() prefixe par "seconds:microsecondes:pid: "), a utiliser pour dater tous les messages * macros-thread.h : un fichier d'utiliaires (macros C) bien pratiques pour simplifier l'utilisation des mutex et des conditions pthread (pour les parties mutex 2.2 et moniteur 2.3)) * makefile : le fichier de construction automatique make all : construit tous les executables make clean : efface tous les fichiers compiles ************************************* ************************************* Sujet de TP : ************************************* ************************************* ************************************* Partie 2.1 : solution a base de semaphores de comptage fichier: lecteurs-redacteurs-mutex.c ************************************* 1) commencez par analyser en detail le contenu des differents fichiers 2) compilez le fichier lecteurs-redacteurs-mutex.c avec le makefile et essayer le programme sans synchronisation. Que ce passe-t-il ? 3) A l'aide de semaphores de comptage , resolvez le probleme des lecteurs redacteurs. Proposez 3 solutions differentes: equite, priorite lecteurs, priorite redacteurs Validez les solutions a l'aide de l'outil JPNS, construisez les reseaux de petri correspondant, et validez-les par simulation. 4) Implementation des solutions (un fichier different par solution) Implementez les solutions avec le module semaphores de comptage propose dans semaphore-moniteur.h, semaphore-moniteur.c. Encadrez chaque operation P() et V() sur les semaphores d'un messsage tprint() afin de tracer/logger l'instant des operations Modifiez la chaine de lancement des processus lecteurs et redacteurs (macros NBTHREADS et STARTING_CHAIN) utilisez un debogueur/devermineur supportant le parallelisme des threads (gdb, ddd, ...). 5) Faites la preuve du bon fonctionnement de la solution priorite redacteur: - en analysant les messages encadrant les operation P() et V() - en utilisant les commandes unix ps, top avec les options adaptees aux threads - en dessinant le chronogramme d'utilisation des operations P() et V() des semaphores de comptage pour l'ensemble des threads lecteurs/redacteurs actives. ************************************* Partie 2.2 : solution a base de semaphores mutex fichier: lecteurs-redacteurs-mutex.c ************************************* 3) A l'aide de semaphores mutex pthreads (verrous ou semaphores binaires), resolvez le probleme des lecteurs redacteurs. Proposez 3 solutions differentes: equite, priorite lecteurs, priorite redacteurs Validez les solutions a l'aide de l'outil JPNS, construisez les reseaux de petri correspondant, et validez-les par simulation. 4) Implementation des solutions (un fichier different par solution) Implementez les solutions avec les mutex pthread (ptread_mutex_* : ptrhread_mutex_t, ptrhread_mutex_init(), ptrhread_mutex_destroy(), ptrhread_mutex_lock(), ptrhread_mutex_unlock() ) Vous pouvez aussi utiliser les macros du module macros-thread.h : INIT_MUTEX(), DESTROY_MUTEX(), P_MUTEX(), V__MUTEX() Encadrez chaque operation P() et V() sur les mutex d'un messsage tprint() afin de tracer/logger l'instant des operations Modifiez la chaine de lancement des processus lecteurs et redacteurs (macros NBTHREADS et STARTING_CHAIN) utilisez un debogueur/devermineur supportant le parallelisme des threads (gdb, ddd, ...). 5) Faites la preuve du bon fonctionnement de la solution priorite redacteur: - en analysant les messages encadrant les operation P() et V() - en utilisant les commandes unix ps, top avec les options adaptees aux threads - en dessinant le chronogramme d'utilisation des operations P() et V() sur les mutex pour l'ensemble des threads lecteurs/redacteurs actives. ************************************* Partie 2.3 : solution a base de moniteurs (mutex et conditions) fichier: lecteurs-redacteurs-moniteur.c ************************************* 1) commencez par analyser en detail le contenu des differents fichiers 2) compilez le fichier lecteurs-redacteurs-mutex.c avec le makefile et essayer le programme sans synchronisation. Que ce passe-t-il ? 3) A l'aide des outils moniteur des pthreads (mutex et conditions), resolvez le probleme des lecteurs redacteurs dans lecteurs-redacteurs-moniteur.c. proposez 3 solutions differentes: equite, priorite lecteurs, priorite redacteurs. 4) Implementation des solutions (un fichier different par solution) Implementez les solutions avec les mutex pthread (ptread_mutex_* : ... ) et les conditions pthread (ptrhread_cond_t, ptrhread_cond_init(), ptrhread_cond_destroy(), ptrhread_cond_wait(), ptrhread_cond_signal() ) Vous pouvez aussi utiliser les macros du module macros-thread.h : INIT_MUTEX(), DESTROY_MUTEX(), P_MUTEX(), V__MUTEX(), et INIT_COND(), DESTROY_COND(), WAIT_COND(), SIGNAL__COND() Encadrez chaque operation P(), V(), WAIT(), SIGNAL() sur les mutex et les conditions d'un messsage tprint() afin de tracer/logger l'instant des operations Modifiez la chaine de lancement des processus lecteurs et redacteurs (macros NBTHREADS et STARTING_CHAIN) utilisez un debogueur/devermineur supportant le parallelisme des threads (gdb, ddd, ...). 5) Faites la preuve du bon fonctionnement de la solution priorite redacteur: - en analysant les messages encadrant les operation P(), V(), WAIT(), SIGNAL() - en utilisant les commandes unix ps, top avec les options adaptees aux threads - en dessinant le chronogramme d'utilisation des operations P(), V(), WAIT(), SIGNAL() sur les mutex et les conditions pour l'ensemble des threads lecteurs/redacteurs actives. ************************************* ANNEXES ************************************* 1) Déboguer les pthreads avec gdb Pour pouvoir controller les threads indépendamment, il suffit d'entrer la séquence de commandes suivante dans gdb: # Enable the async interface. set target-async 1 # If using the CLI, pagination breaks non-stop. set pagination off # Finally, turn it on! set non-stop on Entrer ces commandes dans le fichier ~/.gdbinit pour qu'elles soient prises en compte automatiquement. Pour les détails, voir: Non-Stop Mode 2) Tutoriel débogueur gdb voir : Débuggage avec gdb et Debugging Programs with Multiple Threads commande raccourci effet run r lance le programme (s'arrête au prochain point d'arrêt) continue c relance le programme (s'arrête au prochain point d'arrêt) break xx b xx place un point d'arrêt à la ligne ou à la fonction xx info breakpoints info breakpoints liste les points d'arrêts delete d efface les points d'arrêts next n exécute une instruction (ne rentre pas dans les fonctions) step s exécute une instruction (rentre potentiellement dans les fonctions) finish f exécute les instructions jusqu'à la sortie de la fonction until xx u xx exécute les instructions jusqu'à la ligne xx watch var w var surveille la variable var print expr p expr interprète et affiche expr info threads liste les threads en cours (* devant le thread courant) thread thread-id thread id devient le thread courant 3) Débogueur et IDE débogueurs seuls : gdb, DDD, Kdb, ... environnment de developpement (IDE) : eclipse, Kblocks, KDevelop, Code::Blocks, ... 4) Pour deboguer les pthreads en linux dans netbeans. (préférer eclipse) Ceci peut être fait dans netbeans 7.0. Pour installer c/c++ dans netbeans, suivre les étapes suivantes: - menu "tools/plugins" - dans settings parametrer le proxy "proxy settings" cache.etu.univ-nantes.fr:3128 - dans settings, activez les sources "Certified Plugins, Netbeans Distribution, et Plugin Portal - dans "available plugins" rafraichir le catalogue (update ou refresh), puis installer c/c++ Il faut aussi mettre à jour netbeans: - dans "update" rafraichir le catalogue (update ou refresh), puis bouton update La console gdb est accessible dans menu: "window/debugging/debugger console" La fenêtre de contrôle des threads dans : "window/debugging/threads" Entrer les commandes de la 1ere partie dans le fichier ~/.gdbinit pour qu'elles soient prises en compte automatiquement.