Cours:TdProgSyst : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
(Exercices)
(Exercices)
Ligne 55 : Ligne 55 :
  
 
4.  (Hors TD) Ecrire un programme permettant d’afficher le numéro des signaux reçus par le programme.
 
4.  (Hors TD) Ecrire un programme permettant d’afficher le numéro des signaux reçus par le programme.
 +
 +
=== Duplication de processus ===
 +
La fonction '''fork''' permet à un processus de se dupliquer en mémoire:
 +
le segment de code, le segment de données et la pile sont dupliqués.
 +
Après l’appel de '''fork''', deux processus identiques s’exécutent alors
 +
en mémoire. La valeur de retour de '''fork''' permet de savoir dans quel
 +
processus on se trouve. Si '''fork''' retourne:
 +
 +
* la valeur 0, on est dans le fils.
 +
* une valeur positive, on est dans le père. La valeur retournée est le PID du fils.
 +
* la valeur -1, fork n’a pu s’exécuter pour des raisons diverses: par exemple, plus de mémoire disponible...
 +
 +
Un exemple d'utilisation est:
 +
 +
    #include<sys/types.h>
 +
    #include<unistd.h>
 +
 +
    main() {
 +
    int pid;
 +
    ...
 +
    switch (pid=fork()) {
 +
          case  0:            // -------------------- on est dans le fils
 +
                    ....      // code du fils
 +
                    exit(0);  // fin du fils
 +
          case -1:            // -------------------- erreur du fork
 +
                    perror("erreur dans fork");
 +
                    exit(-1);
 +
          default:            // -------------------- on est dans le père
 +
                    ...        // code du père
 +
          }
 +
    ...
 +
    }

Version du 14 décembre 2015 à 09:40

Td 12 Eléments de programmation système

Gestion des signaux


Deux fonctions du langage C permettent de travailler avec les signaux d’UNIX: la fonction **kill** et **signal**. La première permet d’envoyer un signal à un processus dont on connait le numéro de processus (le PID), et


la fonction signal permet d’associer une fonction écrite par l’utilisateur à un signal UNIX: lorsque ce dernier est reçu, la fonction est exécutée.

Les signaux les plus classiques sont les suivants:

  SIGINT   signal envoyé par UNIX lors d’un Ctrl C pour stopper le processus
  SIGHUP   signal émis par UNIX lors de la déconnexion
  SIGALRM  signal émis par la fonction alarm()
  SIGUSR1  signal à la disposition de l’utilisateur
  SIGUSR2  autre signal à la disposition de l’utilisateur

Un exemple d’utilisation de ces fonctions est représenté ci-dessous:

   #include <stdio.h>
   #include <sys/types.h>
   #include <signal.h>
   void gestion_signal() {
   ...                               // code de gestion du signal
   }
   main() {
   ...
   signal(SIGUSR1,gestion_signal);   // qd on reçoit SIGUSR1, exécute gestion_signal()
   ...
   }

Chaque fois que le processus recevra le signal SIGUSR1, on ira exécuter la fonction gestion_signal. Pour ceux qui connaissent le concept d’ interruption, il s’agit ici d’une interruption logicielle.

La fonction alarm permet à un processus de s’auto-envoyer le signal SIGALRM au bout d’une certaine temporisation exprimée en secondes.

Exercices

1. Ecrire un programme ignorant les arrêts claviers (CTRL+C, ...).

2. Ecrire un programme ignorant le signal émis lors de la déconnexion.

3. Ecrire un programme affichant toutes les dix secondes la chaîne de caractères coucou sur l’écran.

4. (Hors TD) Ecrire un programme permettant d’afficher le numéro des signaux reçus par le programme.

Duplication de processus

La fonction fork permet à un processus de se dupliquer en mémoire: le segment de code, le segment de données et la pile sont dupliqués. Après l’appel de fork, deux processus identiques s’exécutent alors en mémoire. La valeur de retour de fork permet de savoir dans quel processus on se trouve. Si fork retourne:

  • la valeur 0, on est dans le fils.
  • une valeur positive, on est dans le père. La valeur retournée est le PID du fils.
  • la valeur -1, fork n’a pu s’exécuter pour des raisons diverses: par exemple, plus de mémoire disponible...

Un exemple d'utilisation est:

   #include<sys/types.h>
   #include<unistd.h>
   main() {
   int pid;
   ...
   switch (pid=fork()) {
          case  0:            // -------------------- on est dans le fils 
                   ....       // code du fils
                   exit(0);   // fin du fils
          case -1:            // -------------------- erreur du fork
                   perror("erreur dans fork");
                   exit(-1);
          default:            // -------------------- on est dans le père
                   ...        // code du père
          } 
   ...
   }