Redirections, tubes
Ex1
Soit le graphe de processus suivant (un tube est établi entre Pf2 et Pf1f1)
| P
|____
| \ Pf1
| \
| \
|\Pf2 |\
| \ | \Pf1f1
| \ | \
O O O O
()-->--()
-
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 :
16411 sent 16411 16412 received 16411 16411 sent 16411 16412 received 16411 ..... -
Lancez le programme ci-dessus et faites les essais suivants (relancez le programme après chaque essai). Expliquez à chaque fois vos observations.
- Envoyez le signal
SIGSTOPà Pf2, puis le signal SIGCONT à Pf2. - Envoyez le signal
SIGSTOPà Pf1f1, puis le signal SIGCONT à Pf1f1. - Envoyez le signal
SIGTERMà Pf2. - Envoyez le signal
SIGTERMà Pf1f1.
- Envoyez le signal
-
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.
-
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 :
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.