# Redirections, tubes #### Ex1 Soit le graphe de processus suivant (un tube est établi entre Pf2 et Pf1f1) ```bash | P |____ | \ Pf1 | \ | \ |\Pf2 |\ | \ | \Pf1f1 | \ | \ O O O O ()-->--() ``` 1. Ecrivez un programme pipe-ex.c qui implante le graphe ci-dessus (y compris le tube) et tel que : - Pf2 écrive en permanence toutes les 3 secondes son PID dans le tube en affichant ce qu'il écrit - Pf1f1 lise en permanence chaque seconde depuis tube `sizeof(pid_t)` en affichant ce qu'il lit Vérifiez que le programme fonctionne comme prévu, i.e il affiche : ```bash 16411 sent 16411 16412 received 16411 16411 sent 16411 16412 received 16411 ..... ``` 2. Lancez le programme ci-dessus et faites les essais suivants (relancez le programme après chaque essai). Expliquez à chaque fois vos observations. 1. Envoyez le signal `SIGSTOP` à Pf2, puis le signal SIGCONT à Pf2. 2. Envoyez le signal `SIGSTOP` à Pf1f1, puis le signal SIGCONT à Pf1f1. 3. Envoyez le signal `SIGTERM` à Pf2. 4. Envoyez le signal `SIGTERM` à Pf1f1. 3. Modifiez le programme pipe-ex.c en assurant que tous les processus ferment les descripteurs du tube non utilisés. Faites les mêmes essais que ci-dessus et expliquez ce que vous observez. 4. Modifiez encore une fois le programme pipe-ex.c pour que les deux processus Pf1, Pf2 écrivent dans le tube simultanement et que seul Pf1f1 le lise. Qu'observez-vous ? #### Ex2 Un groupe d'étudiants en informatique révise son contrôle de scr. Ils ne peuvent réviser qu'en mangeant de la pizza. Chaque étudiant exécute en boucle : ```c while(1){ prendre_une_part_de_pizza(); reviser_et_manger_la_part_de_pizza(); } ``` Quand il n'y a plus de pizza, les étudiants dorment. Celui qui prend la dernière part commande une nouvelle pizza. Écrire un programme en C qui crée les processus fils étudiants (leur nombre est passé à la ligne de commande). Les parts de pizza, numérotés de 1 à 8, sont placées dans un tube par le pére. Les fils connsomment chaque part depuis le tube. Un autre tube permet à celui qui prend la dernière part d'en commander une autre. Exemple de trace d'exécution ``` [denis@portabledenis test]$ ./pizza 10 student 1 takes piece 1 student 8 takes piece 2 student 0 takes piece 3 student 3 takes piece 4 student 9 takes piece 5 student 2 takes piece 6 student 4 takes piece 7 student 5 takes piece 8 student 5 orders a pizza pizza ordered! pizza delivered! student 6 takes piece 1 student 7 takes piece 2 student 9 takes piece 3 student 0 takes piece 4 student 5 takes piece 5 student 2 takes piece 6 student 1 takes piece 7 student 6 takes piece 8 student 6 orders a pizza pizza ordered! pizza delivered! student 4 takes piece 1 student 3 takes piece 2 student 8 takes piece 3 student 7 takes piece 4 student 9 takes piece 5 student 5 takes piece 6 student 2 takes piece 7 student 6 takes piece 8 student 6 orders a pizza pizza ordered! pizza delivered! student 0 takes piece 1 student 8 takes piece 2 student 7 takes piece 3 ... ``` #### Ex3 Le but est d'implanter une architecture client/serveur en utilisant des tubes nommés. (Il existe pour cela un autre mécanisme dédié à la communication locale interprocessus avec les sockets) ``` +-------------+ +----------> | clt1 pipe | --------------------------+ | +-------------+ | | | | +-- client1 <--+ | | | | | +-------------+ <-+ +-- serveur <-------- | serveur pipe| <---- client2 <-------+ | +-------------+ <-+ | | | | | | | | +-- client3 <---+ | | +-------------+ | | +----------> | clt3 pipe | ---------------------------+ | | +-------------+ | | | | +-------------+ | +----------> | clt2 pipe | -------------------------------+ +-------------+ ``` **Le serveur** Il permet de consulter les notes d'étudiants à un examen d'ASR. Il récupére en boucle les requêtes des clients dans un tube nommé `srv.pipe`. Pour écouter en boucle les demandes des clients (lecture bloquante), le serveur ouvre le tube en mode lecture/écriture (il y a toujours un écrivain, même lorsqu'on n'a plus aucun client). Chaque requête est composée : - du pid du client - du numéro de l'étudiant dont on veut la note. Pour chaque requête, le serveur crée un fils qui renvoie la note de l'étudiant correspondant à la requête, en utlisant le tube nommé `/tmp/clt.pid`. On prendra soin de traiter correctement le signal `SIGCHLD`. **Le client** - Il crée le tube nommé pour la réponse à sa requête. - Il envoie sa requête dans le tube `srv.pipe`. - Il récupère la réponse du serveur dans son tube nommé, et le détruit.