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 :

Problème de réception de signaux


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 228
    Par défaut Problème de réception de signaux
    Bonjour
    je suis entrain de réaliser un serveur qui reçoit des signaux (via kill)


    voila monde code
    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
     
    #include "../include/header.h"
     
    t_data	data;
     
    void handler(int sig, siginfo_t *info, void *cont)
    {
      data.pid = info->si_pid;
      if (sig == SIGUSR1)
        data.signal_h = 0;
      else if (sig == SIGUSR2)
        data.signal_h = 1;
      (void)cont;
    }
     
    void	display_pid()
    {
      my_printf("Server PID : ");
      my_printf("%d\n",getpid());
    }
     
    int			main()
    {
      struct sigaction	sVal;
      int	i;
      int	value;
      value = 0;
      i = 1;
      display_pid();
      data.signal_h = -1;
      sVal.sa_flags = SA_SIGINFO;
      sVal.sa_sigaction = &handler;
      sigemptyset(&sVal.sa_mask);
      sigaction(SIGUSR1, &sVal, NULL);
      sigaction(SIGUSR2, &sVal, NULL);
      while (42)
        {
          pause();
          if (i == 9)
          	{
    	  printf("%c",value);
    	  value = 0 ;
          	  i = 1;
          	}
          if (data.signal_h == 1)
    	value += pow(2, 8 - i);
          data.signal_h = -1;
          i++;
          /* usleep(100); */
          kill(data.pid, SIGUSR1);
        }
    }
    et voila le fichier header.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <sys/types.h>
    #include <unistd.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct  s_data
    {
      int   signal_h;
      int   pid;
    }               t_data;
    le probleme c'est qu'il ne capte pas toujours les signaux qu'il recoit , le programme reste defois en pause , je ne comprend pas pourquoi
    Pouvez vous m'aider ?

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Bonjour,

    Ce cas d'étude est absolument atroce ! Il rassemble exactement tout ce qu'il ne faut pas faire et tu n'es malheureusement pour rien. Ces problèmes ont été dissertés ici de nombreuses fois. Fais une recherche, mais concrètement :

    • Les signaux sont classés dans les IPC parce qu'ils comptent effectivement au nombre des rares mécanismes qui permettent à un processus d'influer sur un autre mais ils ne servent absolument pas à faire de la transmission de données, ni du message passing. Ils préemptent le processus en cours. Il faut les voir comme des interruptions logicielles, fonctionnant un peu sur le modèle des IRQ ;
    • Un signal est relativement violent. Non seulement, il interrompt le processus mais implique une action du système, un passage en mode noyau, et cela introduit énormément de latence. Un signal doit donc être occasionnel et justifié ;
    • Lorsque tu es en train de gérer un signal, les signaux du même type arrivant pendant ce traitement sont bloqués et ignorés (comme les IRQ). Chaque signal en instance lève son propre flag. Il n'y a pas de file de signaux en attente ;
    • Un gestionnaire de signal à l'ancienne sauce était même censé n'être déclenché qu'une seule fois par défaut et était censé fonctionner comme un disjoncteur. Une fois revenu à la normale, il fallait manuellement réarmer le gestionnaire en ré-appelant signal() (éventuellement depuis le gestionnaire lui-même). Ce n'est plus le cas par défaut avec sigaction, mais l'esprit demeure ;
    • Si le traitement d'un signal est lent par nature et qu'il ne cumule pas les signaux d'un même type en attente, alors tu vas forcément perdre des informations si tu les envoies en boucle et sans contrôle.


    Et par ailleurs :

    • value += pow(2, 8 - i); est également la pire façon qui soit de remplir un champ de bits (ce qui pourrait paraître étrange de prime abord à un mathématicien pur) :
    • Utilise les opérateurs de décalage « << » et « >> » qui servent à cela et qui sont eux-mêmes impliqués dans les calculs de plus haut niveau que tu utilises ;
    • Utilise les opérateurs logiques OU (« | ») et ET (« & ») pour faire de la manipulation de bits. Considère que chez les programmeurs, on utilise six opérateurs fondamentaux et plus quatre (« + - × ÷ »). Après on y ajoute le négateur et le OU exclusif.
    • Si tu cumules tes bits avec « + » et si pour une raison quelconque, le bit de destination est déjà à 1, alors ton opération va inverser sa valeur et va modifier potentiellement la valeur de tous les bits de rang supérieur ;
    • pow() n'est pas un opérateur mais une fonction complexe, fournie par une bibliothèque, coûteuse en temps et en ressources (toutes proportions gardées) et qui s'appuie sur les logarithmes pour proposer un résultat quelque soit la valeur et la nature de ses paramètres, puisque ses arguments sont réels et qu'élever un nombre à une puissance non entière est autrement plus compliqué que de multiplier n fois un nombre par lui-même, même avec un algorithme rapide.


    Si c'est un cas de figure qui t'est imposé par ton école, alors mène l'exercice au mieux que tu le peux mais non sans protester car présenter ce genre d'approche à un entretien d'embauche te conduira inévitablement à te faire recaler.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 228
    Par défaut
    Merci de tes réponses , je prend en comptes.
    Cependant c'est effectivement un projet étudiant imposé par une école.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    A chaque fois que la fonction pause() est débloquée, on émet un SIGUSR1.

    Ce qui peut compliquer la lisibilité est selon moi :
    • Si un autre signal est reçu, on émettra un SIGUSR1 quand même
    • S'il existe plusieurs threads dans le process, un signal reçu pourra interagir avec un des autres (un signal provoque le déblocage d'un seul thread mis en attente). Et pause() resterait alors bloqué.
    • Le signal peut être reçu pendant les printf() du code car ils contiennent en interne des micro-états d'attente. Et pause() resterait alors bloqué.

    Je te propose de tracer ces cas en modifiant ton handler (qui lui ne peut pas perdre de signaux), qui pourrait incrémenter 3 compteurs (cas SIGUSR1, cas SIGUSR2, et autre cas) en installant le handler sur d'autres signaux.
    Que l'on peut tester immédiatement après la pause(), un simple affichage des trois pourrait suffire à l'analyse.

    Le sa_mask est mis à zéro donc rien n'est masqué pendant ton handler, tu pourrais à la placer masquer tous les signaux pour limiter les intrusions mais je crois peu à cette possibilité.

    Mais s'il te plait ôte cet infâme pow().

Discussions similaires

  1. Réponses: 7
    Dernier message: 12/06/2007, 11h07
  2. Des pages supprimés du serveur qui réaparraissent de nouveau ?!
    Par ninj@ dans le forum Autres hébergeurs
    Réponses: 3
    Dernier message: 28/02/2007, 00h11
  3. Serveur qui bloque au démarrage
    Par DiabloZizi dans le forum Ordinateurs
    Réponses: 5
    Dernier message: 11/11/2006, 13h54
  4. Relancer tout seul un serveur qui plante
    Par guidav dans le forum Requêtes
    Réponses: 2
    Dernier message: 02/08/2006, 17h02
  5. [J2EE] mémoire du serveur qui s'évapore ?
    Par Arnaud Giuliani dans le forum Wildfly/JBoss
    Réponses: 3
    Dernier message: 09/06/2006, 16h32

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