IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Attente d'un signal !


Sujet :

C

  1. #1
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 466
    Points : 19 456
    Points
    19 456
    Par défaut Attente d'un signal !
    Bonjour à tous.

    J'essaye de comprendre comment fonctionne les signaux sous Unix.
    Pour ce faire, j'ai repris le livre de Jean-Marie Rifflet "La programmation sous UNIX" (3ième édition) et en particulier le chapitre 14 consacré à "La gestion des signaux".

    J'ai repris l'exemple du paragraphe 14.8.2 consacré à "La primitive sigsuspend". Voici l'exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <unistd.h>
     
    pid_t		pid_fils;
     
    /*******************************/
    /*                             */
    /*     Handler des Signaux     */
    /*                             */
    /*******************************/
     
    void handler_pere(int signo)
    {
    	static int nbre_recu = 0;
     
    	switch (signo)
    	{
    		case SIGUSR1:	nbre_recu++;
    				break;
     
    		default:	printf("\nNombre d'exemplaires reçus ..: %d\n", nbre_recu);
    				exit(0);
    				break;
    	}
    }
     
    void handler_fils(int signo)
    {
    	static int nbre_envoye = 0;
     
    	switch (signo)
    	{
    		case SIGUSR1:	nbre_envoye++;
    				break;
     
    		default:	printf("Nombre d'exemplaires envoyés : %d\n", nbre_envoye);
    				exit(0);
    	}
    }
     
    /********************************/
    /*                              */
    /*     Procédure Principale     */
    /*                              */
    /********************************/
     
    int main(void)
    {
    	sigset_t		mask1;
    	struct sigaction	action1;
     
    	printf("Début du processus Père\n");
     
    	sigemptyset(&mask1);
    //	sigaddset(&mask1, SIGUSR1);
    	sigprocmask(SIG_BLOCK, &mask1, NULL);
     
    	action1.sa_handler = handler_pere;
    	sigaction(SIGUSR1, &action1, NULL);
    	sigaction(SIGINT,  &action1, NULL);
     
    	sigemptyset(&mask1);
    	sigprocmask(SIG_BLOCK, &mask1, NULL);
     
    	if ((pid_fils = fork()) == 0)
    	{
    		/*========================*/
    		/*     Processus Fils     */
    		/*========================*/
     
    		sigset_t		mask2;
    		struct sigaction	action2;
     
    		printf("Début du processus Fils\n");
     
    		sigemptyset(&mask2);
    		sigprocmask(SIG_BLOCK, &mask2, NULL);
     
    		action2.sa_handler = handler_fils;
    		sigaction(SIGUSR1, &action2, NULL);
    		sigaction(SIGINT,  &action2, NULL);
     
    		for (int i=0; i<100000; i++)
    		{
    			kill(getppid(), SIGUSR1);
    			sigsuspend(&mask2);
    		}
     
    		printf("Fin   du processus Fils\n");
    		exit(0);
    	}
     
    	for (int i=0; i<100000; i++)
    	{
    		sigsuspend(&mask1);
    		kill(pid_fils, SIGUSR1);
    	}
     
    	printf("Fin   du processus Père\n");
    	exit(0);
    }
    Je l'ai légèrement modifié en dissociant les variables mask et action pour chaque processus.
    A vrai dire, cela ne change rien à mon problème.

    Quand je le lance tel quel, et que je compte dans ma tête jusqu'à 10, je tape au clavier un ctrl+c pour provoquer un "SIGINT".
    Voici le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ~/Prog_C/ex_04> signal
    Début du processus Père
    Début du processus Fils
    ^C
    Nombre d'exemplaires reçus ..: 49
    Nombre d'exemplaires envoyés : 49
    ~/Prog_C/ex_04>
    Si maintenant je supprime le commentaire "//" et que je lance à nouveau le programme, dans les mêmes conditions, voici le nouveau résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ~/Prog_C/ex_04> signal
    Début du processus Père
    Début du processus Fils
    ^C
    Nombre d'exemplaires reçus ..: 94612
    Nombre d'exemplaires envoyés : 94611
    ~/Prog_C/ex_04> signal
    Comme vous pouvez le constater, avec le commentaire, le nombre de signaux est très faible (49 dans cet exemple), alors sans le commentaire, le nombre de signaux est bien plus important (94612).

    1) en quoi le fait de mettre la ligne en commentaire ou pas, a une influence sur la rapidité du traitement des signaux ?

    2) pourquoi écrire dans le programme, pour le processus 1, d'abord l'interdiction du signal SIGUSR1", puis après l'action, supprimer cette interdiction ?
    Autrement dit, je ne comprends pas l'intérêt de déclarer un blocage d'un signal, pour ensuite ne plus le bloquer.

    Merci.
    @+

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 466
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 466
    Points : 19 456
    Points
    19 456
    Par défaut
    Salut à tous.

    En utilisant, dans la fonction "SIGPROCMASK()", le paramètre "SIG_BLOCK" au lieu de "SIG_SETMASK", nous créons le nouveau masque en concaténant le nouvelle ensemble avec l'ancien ensemble des signaux bloqués.
    Ce qui donne tout son sens, à cette première partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sigemptyset(&mask1);
    sigaddset(&mask1, SIGUSR1);
    sigprocmask(SIG_BLOCK, &mask1, NULL);
    qui deviendra l'ancien ensemble des signaux bloqués.

    Par contre, je ne comprends pas le fonctionnement de cette exercice, même en relisant les notes dans le bouquin de Rifflet (page 445).

    Est-ce que quelqu'un peut m'expliquer le fonctionnement de cet exercice ?

    @+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 22/05/2010, 11h50
  2. [VB6] [MDI] Signaler la fermeture d'une fille à la mère
    Par cpri1shoot dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 13/04/2004, 08h57
  3. Délai d'attente expiré
    Par amiral thrawn dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 15/04/2003, 12h04
  4. recupèrer file d'attente d'impression
    Par magic corp. dans le forum Langage
    Réponses: 2
    Dernier message: 25/09/2002, 14h12
  5. [Choix] Quelles attentes par rapport aux SGBD ?
    Par thierry34 dans le forum Décisions SGBD
    Réponses: 6
    Dernier message: 13/07/2002, 20h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo