Programmation Système et Réseau
TP n° 3




Notions abordées :


Exercice 1.


Expliquer le fonctionnement du programme suivant.
   
#include   <stdlib.h>
#include   <stdio.h>
#include   <sys/types.h>
#include   <unistd.h>
#include   <sys/wait.h>
#include   <signal.h>
struct sigaction action;
void hand_sigusr1(int sig){
       printf("(de %d) Signal SIGUSR1 recu\n", getpid());
       exit(0);
}
int main() {
  pid_t pid;
  int i = 0;
  int status;
  action.sa_handler=hand_sigusr1;
  sigaction(SIGUSR1,&action,NULL);
  if((pid=fork())==0){
     printf("Je suis le fils de PID %d\n", getpid());
     /* processus fils bouclant */
     while(1) { i = 0; };
  }
  printf("Je suis le pere de PID %d\n", getpid());
  if(kill(pid,0)==-1){
     printf("(de %d) Fils %d inexistant\n", getpid(), pid);
  }
  else{
     printf("(de %d) Envoi du signal SIGUSR1 au processus %d\n", getpid (), pid);
     kill(pid,SIGUSR1);
  }
  pid=waitpid(pid,&status,0);
  printf("(de %d) Status du fils %d : %d\n",getpid(),pid,status);
}




Exercice 2.

(Dispositif de l'homme mort.) Ecrire un programme qui prend un entier n en argument sur la ligne de commande et compte à rebours à partir de n : le programme doit afficher les valeurs n, n-1, n-2, ... à raison d'une valeur toutes les secondes et il termine si le compteur atteint 0. Si l'utilisateur tape Ctrl+C avant que le compteur arrive à 0, alors le compte rebours reprend à partir de n.

Exemple d'exécution :

$ compte-a-rebours 5
 5 4 3 2
  (l'utilisateur tape Ctrl+C)
 5 4 3 2 1 0
  Alerte : vous dormez !
$



Exercice 3.

(Jeu de dés.) Ecrire un programme qui boucle en attendant que l'utilisateur tape Ctrl+C. Lorsque l'utilisateur tape Ctrl+C, le programme choisit aléatoirement 2 valeurs entre 1 et 6 et les affiche. Le programme termine lorsque l'utilisateur tape 2 fois Ctrl+C en moins d'1 seconde.          
               
Exemple d'exécution :

$ jeu-de-des
 (appui sur Ctrl+C)
 2 3    
 (appui sur Ctrl+C)
 5 1
 appui sur Ctrl+C)
 6 6
 (appui 2 fois rapidemment sur Ctrl+C)             
$


Exercice 4.

La suite de Syracuse est définie par :

                              u(n+1) = u(n)/2, si u(n) est pair
                                              3u(n) + 1, sinon

Une conjecture est que quelque soit le terme initial u(0) (non nul) de la suite, celle-ci finit par valoir 1 (puis par boucler sur 4, 2, 1). Etant donnée une valeur initiale u(0) de la suite, on appelle temps de vol, le plus petit indice k pour lequel u(k) = 1 pour la première fois, et altitude maximale la valeur maximale prise par la suite durant ce temps de vol. Nous utilisons un pro-
gramme calculant la suite de Syracuse pour chaque valeur initiale comme exemple d’utilisation possible des signaux.
    Pour simplifier, les variables liées à la suite de Syracuse seront globales.
   
   1. Ecrire une fonction void syracuse() qui étant donnée une valeur initiale calcule les termes de la suite de Syracuse jusqu’à ce qu’elle vaille 1.

   2. Faire une boucle infinie pour i = 1, 2, 3, . . . qui fixe u(0) = i et lance le calcul précédent. Le programme boucle indéfiniment sans rien afficher.

   3. Faire en sorte qu’à la réception du signal SIGTSTP (Ctrl-Z), le programme affiche la valeur initiale courante, l’indice du dernier terme calculé et la valeur prise par la suite, sans stopper le programme.

   4. Faire en sorte que Ctrl-C (SIGINT) termine le programme en affichant : la plus grande valeur initiale testée ; l’altitude maximale atteinte et la valeur initiale pour laquelle cette altitude maximale est atteinte ; le temps de vol maximal et la valeur initiale pour laquelle ce temps de vol a été atteint.

   5. Faire en sorte que Ctrl-C ne termine pas le programme mais que retaper Ctrl-C dans les deux secondes termine le programme (utiliser une alarme).


Exercice 5.

On souhaite faire un programme qui :
   – crée un tube et N processus fils où N est donné en argument.
   – Lorsqu’il reçoit le signal SIGUSR1, le père écrit un nombre sur le tube et renvoie le signal SIGUSR2 au fils qui à émis SIGUSR1.
    – Chaque fils :
         – s’il n’a rien à faire émet le signal SIGUSR1 au père.
         – s’il reçoit le signal SIGUSR2, lit le nombre dans le tube et exécute un calcul long sur ce nombre (on pourra simplement endormir le processus pendant 5 secondes).