[C][Linux]Que fait un programme qui reçoit un signal ?

Que fait un programme qui reçoit un signal ? [C][Linux] - C - Programmation

Marsh Posté le 03-02-2009 à 18:27:41    

Bonjour,
 
je programme sous Linux et je fais un appel à la fonction "signal" pour enregistrer une fonction sur un signal (SIGUSR1).
J'aimerais savoir ce que fait le programme quand il reçoit le signal. J'envisage deux possibilités : il fait un jump à la fonction enregistrée et reprend son execution à la fin de celle-ci, ou bien il crée un thread qui éxecute la fonction enregistrée pendant qu'il continue à tourner.  
Je suis également très preneur si vous connaissez un PDF à ce sujet.
 
Merci d'avance :)

Reply

Marsh Posté le 03-02-2009 à 18:27:41   

Reply

Marsh Posté le 03-02-2009 à 20:06:55    

il fait un jump, pas de thread.
man signal, toussa

Reply

Marsh Posté le 04-02-2009 à 10:34:57    

Ok merci. En fait j'ai trouvé une page assez complète sur les signaux :
http://www.cs.utah.edu/dept/old/te [...] ry_21.html
En revanche ce qui est bizarre c'est que cette page dit que Linux bloque automatiquement un signal si on est dans une fonction qui traite ce signal (pour des raisons assez logiques de protection de données), et pourtant je n'ai pas ce comportement.
J'enregistre une fonction avec signal (SIGUSR1, signal_handler), et j'envoie les signaux avec la fonction kill dans un autre programme, et si j'envoie très rapidement deux fois le signal, la fonction signal_handler commence une deuxième fois avant que la première occurrence ne soit finie :/ Je regarde pour utilise sigaction pour voir si change de comportement.

Reply

Marsh Posté le 04-02-2009 à 11:09:12    

Les programmes sont souvent construits pour que, dès qu'un signal arrive, une thread est lancée pour traiter le signal. Quand plusieurs signaux arrivent rapidement, il peut y avoir plusieurs threads qui tournent en même temps.


Message édité par olivthill le 04-02-2009 à 11:10:17
Reply

Marsh Posté le 04-02-2009 à 12:56:06    

Il faut éviter d'utiliser signal(), et utiliser sigaction() à la place. Tu constatera que sigaction() a prévus un moyen de spécifier si oui ou non on veut permettre à un signal handler d'être a nouveau interrompu par le même signal. Il est également possible de spécifier les signaux qu'ont veut masquer pendant qu'on se trouve dans le signal handler.
 
Par défaut, quand tu installes un signal handler avec sigaction(), le signal qui a déclanché l'appel du handler est masqué. Les autres signaux ne sont pas masqués.

Reply

Marsh Posté le 04-02-2009 à 15:26:12    

Bah là c'est moi qui reçoit le signal, et je crée pas de thread à ce moment là. Et pourtant, que j'installe le handler avec signal ou avec sigaction il peut être appelé deux fois à la suite (se superposant) si je mets trop d'instructions dedans. Donc tant pis j'ai rendu mon programme un poil moins rapide mais plus propre, en ne faisant qu'une instruction du type "new_signal = 1" dans le handler et en utilisant cette variable globale dans une while (1) qui dort mais qui se réveille assez souvent.
Merci pour vos remarques :)

Reply

Marsh Posté le 04-02-2009 à 20:42:13    

nan mais kill, c'est pas géré par la victime ... le noyau il défonce le truc et basta.

Reply

Marsh Posté le 04-02-2009 à 22:45:03    

Est-tu 100% qu'il est appelé à nouveau alors que tu es encore dans le handler ?
Si c'est le cas, peut-être que la deuxième fois il est appelé pour un signal différent ?

Reply

Marsh Posté le 04-02-2009 à 23:01:04    

Je disais signal/raise parce que ce sont les seules ANSI

Reply

Marsh Posté le 05-02-2009 à 17:35:42    

non non c'est bien le même signal (printf du signum, deuxième argument du handler)
 
et j'accepte d'être POSIX non ANSI ;)

Reply

Marsh Posté le 05-02-2009 à 17:35:42   

Reply

Marsh Posté le 08-02-2009 à 13:16:27    

J'ai posé une question similaire sur un forum il y a peu de temps, c'est encore tout frais:)
 
Par définition la fonction appelée par le signal doit effectuer un minimum de traitements.  La réception du signal interrompt toute action en cour et laisse la mémoire dans un état incertain. C'est pour cela qui faut faire le moins d'action possible et surtout ne pas utiliser de primitives. Elle doit simplement modifier quelques marqueurs qui indiqueront à ton programme l'action qu'il doit effectuer.
 
 
De plus un marqueur doit être modifié en un seul accès mémoire, pour ne pas créer de conflit.  
Il doit être déclaré comme ceci :
 

Code :
  1. static volatile sig_atomic_t flag;


 
A la charge de ton programme de tester la valeur du signal et de déclencher les traitement adéquats.
 
Un bon pdf si ça t'interesse  : http://www.advancedlinuxprogrammin [...] chargement
 
Ciao

Reply

Marsh Posté le 09-02-2009 à 10:02:25    

Merci, c'est effectivement comme cela que je procède maintenant, même si cela peut rajouter un peu de latence au traitement il y a moins de questions à se poser sur la protection de données.
Et le livre est effectivement très bien fait, en plus en français ! :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed