Cyril Rabat


TP n°5 : les signaux

 Télécharger en PDF

   Le but de ce TP est de manipuler les appels systèmes relatifs à la gestion des signaux.

 

Les questions subsidiaires ne sont à faire que si vous avez du temps. Le dernier exercice correspond au sujet du mini-projet 2.

Positionnement de gestionnaire

   Dans cet exercice, nous souhaitons vérifier le comportement de la fonction sigaction.

Questions

  1. Écrivez un programme qui se met en pause pendant 10 secondes à l'aide de la fonction alarm. Une fois les 10 secondes passées, le programme affiche un message puis termine normalement.
  2. Écrivez un programme qui se met en pause pendant 10 secondes et qui compte le nombre de signaux SIGINT reçus. Une fois la pause terminée, le programme affiche le nombre de signaux reçus.

Questions subsidiaires

  1. Écrivez un programme qui positionne un gestionnaire sur les signaux SIGUSR1 et SIGUSR2 qui permet d'afficher un message personnalisé pour chacun de ces signaux. Le programme continue son exécution (qui correspond à une boucle infinie) tant que le signal SIGINT n'est pas reçu. Bien sûr, le programme doit quitter normalement sur le return du main une fois le signal SIGINT reçu. Les signaux doivent être envoyés depuis le terminal à l'aide de la commande kill.
  2. Modifiez le programme précédent pour que les gestionnaires des signaux SIGUSR1 et SIGUSR2 mettent en pause le processus pendant 10 secondes.
    • Que se passe-t-il si un signal est reçu avant la fin de la pause ?
    • Remplissez ou videz l'ensemble correspondant au champ sa_mask pour vérifier les différences de comportement.

Prise en main des ensembles de signaux

   L'objectif de cet exercice est de tester le fonctionnement de sigprocmask, sigpending et sigaction, ainsi que les fonctions de gestion des ensembles de signaux.

Questions

  1. Écrivez un programme qui bloque tous les signaux puis se met en pause pendant 20 secondes.
    • Peut-on utiliser la fonction sleep pour la pause ?
    • Et la fonction alarm ?
    • Vérifiez que les signaux sont bien bloqués pendant la pause (augmentez la durée si nécessaire).
    • Que se passe-t-il si le signal SIGKILL est envoyé ?
  2. Après les 20 secondes de pause, le programme doit afficher les signaux reçus pendant sa pause.
    • Modifiez le programme pour afficher le code des signaux reçus.
    • Est-il possible de savoir si plusieurs signaux du même type ont été reçus ?

Questions subsidiaires

  1. Modifiez le programme pour qu'un gestionnaire soit positionné sur le signal SIGINT puis qui attend 20 secondes avant le blocage de tous les signaux (le code de la question précédente). Le gestionnaire affiche simplement un message à chaque réception de signal.
    • Écrivez les modifications demandées.
    • Pourquoi ne peut-on pas utiliser sleep pour l'attente de 20 secondes ?
    • Le gestionnaire est-il encore appelé lorsque les signaux sont bloqués ?

Signaux temps-réel

   L'objectif de cet exercice est de manipuler les signaux temps-réel.

Questions

  • Dans cette question, nous souhaitons écrire deux programmes. Le premier programme attend la réception du signal SIGRTMIN et retourne ce même signal au processus qui lui a envoyé. Le deuxième programme prend en argument le PID du processus correspondant au premier programme et lui envoie un signal SIGRTMIN. Il se met ensuite en attente d'un signal SIGRTMIN.
    • Comment le premier programme peut-il récupérer le PID du deuxième programme à la réception du signal ?
    • Comment faire en sorte que l'attente soit une attente passive ?
    • Écrivez les programmes.
  • Modifiez le deuxième programme pour qu'il envoie en plus un entier spécifié en argument (en plus du PID du premier programme). Le premier programme affiche l'entier reçu et renvoie le double. Le deuxième programme affiche la valeur de l'entier reçu.

Nombres premiers

 

Cet exercice correspond au mini-projet obligatoire. Finalement, il est tellement bien, qu'il pourrait même être réutilisé en partie pour le projet final...

   Nous souhaitons réaliser une application distribuée qui permet de calculer la primalité de nombres entiers. Pour cela, nous allons écrire une application de type producteur/consommateur. Le producteur crée les tâches (correspondant à un nombre entier impair de X chiffres) et les consommateurs testent la primalité. Les tâches sont envoyées dans un tube nommé (le tube des tâches) et les résultats envoyés dans un second tube nommé (le tube des résultats).

   Le producteur correspond à une application ncurses qui prend en arguments la valeur X, le nombre maximum de consommateurs (noté N) et le nom des deux tubes nommés. L'interface est découpée en deux : N carrés rouges/verts qui indiquent les consommateurs connectés/déconnectés et une fenêtre dans laquelle défilent les informations (nombres premiers trouvés, consommateurs connectés/déconnectés, etc.). Le producteur possède deux fils qui lui envoient les informations à l'aide d'un unique tube anonyme. Le producteur met à jour l'interface ncurses en fonction des données reçues. Quand l'utilisateur presse CRTL+C dans le producteur, un signal SIGINT est envoyé aux deux fils pour leur demander de s'arrêter.

   La gestion des connexions est réalisée par un fils du producteur nommé gestionnaire de connexions. Pour se connecter à l'application, un consommateur doit envoyer un signal au gestionnaire de connexions (SIGRTMIN) qui lui renvoie un signal (SIGRTMIN) associé à une valeur lui indiquant si oui ou non, il peut se connecter (si le nombre maximum de fils est atteint ou non). Quand un consommateur s'arrête (lorsque l'utilisateur fait un CTRL + C), un signal (SIGRTMIN+1) est envoyé au gestionnaire de connexions. À chaque connexion/déconnexion, le gestionnaire de connexions avertit son père via un tube anonyme. Quand le gestionnaire de connexions reçoit un signal SIGINT, il envoie un message SIGRTMIN+1 à chaque consommateur qui s'arrête, puis il s'arrête à son tour.

   La gestion des tâches est réalisée par un fils du producteur, nommé gestionnaire de tâches. Le gestionnaire de tâches écrit les tâches dans le tube puis se met en attente de réponses. Dès qu'une réponse est reçue, elle est envoyée au producteur. Quand il reçoit un signal SIGINT, il s'arrête.

   Le consommateur prend en arguments le PID du gestionnaire de connexions, ainsi que le nom des deux tubes nommés. Il envoie un signal SIGRTMIN au gestionnaire de connexions et attend la réponse (SIGRTMIN avec le code d'état). Si le code est OK, il peut lire une tâche dans le tube des tâches, la traiter (calculer si le nombre est premier) puis envoyer le résultat dans le tube des résultats. Et ainsi de suite. Il s'arrête lorsqu'il reçoit un signal SIGINT (il envoie alors un signal SIGRTMIN+1 au gestionnaire de connexions) ou un signal SIGRTMIN+1.

Conseils

  1. Faites un schéma de l’application en représentant les différentes applications et fils.
  2. Faites les diagrammes d’échanges (signaux et tubes).
  3. Écrivez la partie gestion des connexions. Le gestionnaire de connexions est un programme qui attend les connexions (signaux SIGRTMIN) et les déconnexions (signaux SIGRTMIN+1) et qui affiche simplement les informations à l'écran. Il s'arrête quand on presse CRTL+C (et envoie alors un SIGRTMIN+1 à chaque consommateur). Le consommateur se contente de se connecter (envoi d'un signal SIGRTMIN et attente d'un signal SIGRTMIN avec le code d'état) puis d'attendre un signal SIGINT (envoi d'un signal SIGRTMIN+1 au gestionnaire de connexions) ou SIGRTMIN+1 (il s'arrête alors).
  4. Écrivez la partie gestion des tâches. Le gestionnaire de tâches crée les deux tubes nommés. Il envoie les tâches dans le tube des tâches et attend les résultats dans le tube des résultats. Un consommateur se contente de lire des tâches depuis le tube des tâches, de les calculer, puis d'envoyer les résultats dans le tube des résultats.
  5. Écrivez maintenant le programme global, sachant qu'il s'agit de regrouper les applications précédentes.

Outils


Version de cette page Jeudi 15 Février 2018

© Cyril Rabat 2016

Connexion

Mot de passe perdu

Dernières nouvelles

Aucune pour le moment

Contact

Courriel :
cyril.rabat [at] univ-reims.fr

Téléphone :
+33-326-91-33-81

Fax :
+33-326-91-33-97

Facebook :
lien Facebook direct