Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

pthread et signaux

6 réponses
Avatar
fabrizio
Bonjour,

Si ce forum n'est pas adapté, merci de bien vouloir me rediriger.

Ci-dessous un bout de code qui se compile ainsi :
g++ -o thread thread.c -lpthread

Je voudrais savoir deux choses :
- Cette implémentation s'inspire du chapitre 12 de "La programmation
système en C sous Linux" par C. Blaess (2ème éd.) : cette méthode vous
paraît-elle correcte ? C'est à dire : dédier un thread à la gestion des
signaux.
- Voici une trace d'exécution (stoppée par un SIGQUIT) :
$ ./thread
thread main
SIGINT
Quit

Le gestionnaire handler() ne semble jamais appelé (il n'imprime pas en
tout cas). Pourquoi ?
Si j'omets d'installer un gestionnaire pour les signaux, sigwait() ne
retourne jamais. Pourquoi ?

Toute aide sera la bienvenue,
F.

-thread.c-
#include <stdio.h>
#include <pthread.h>
#include <signal.h>

void handler(int sig) {
printf("caught signal %d\n",sig);
}

void* sig_routine(void* param) {
struct sigaction action;
sigfillset(&action.sa_mask);
action.sa_handler = handler;
action.sa_flags = 0;
sigaction(SIGINT, &action, NULL);
sigaction(SIGCHLD, &action, NULL);

sigset_t mask;
sigemptyset(&mask);
if (pthread_sigmask(SIG_SETMASK, &mask, NULL) )
printf("pthread_sigmask failed\n");
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGINT);
int sig;
while (1) {
sigwait(&mask, &sig);
switch(sig) {
case SIGINT:
printf("SIGINT\n");
break;
case SIGCHLD:
printf("SIGCHLD\n");
default:
printf("SIG=%d\n",sig);
break;
}
}
return(NULL);
}

int main() {
pthread_t tsig, t1;
if (pthread_create(&tsig, NULL, sig_routine, NULL))
printf("pthread_create failed\n");
sigset_t mask;
sigfillset(&mask);
if (pthread_sigmask(SIG_SETMASK, &mask, NULL))
printf("pthread_sigmask failed\n");
while (1) {
printf("thread main\n");
sleep(1);
}
return(0);
}
---------

6 réponses

Avatar
Alain Ketterlin
fabrizio writes:

Je voudrais savoir deux choses :
- Cette implémentation s'inspire du chapitre 12 de "La programmation
système en C sous Linux" par C. Blaess (2ème éd.) : cette méthode vous
paraît-elle correcte ? C'est à dire : dédier un thread à la gestion des
signaux.


C'est à mon avis une des meilleures solutions. Le problème entre
signaux (envoyés à un processus) et les threads (donc pas les
processus) c'est que le signal est traité par n'importe quel thread du
processus si on ne fait rien. On a souvent pas envie de cela (ne
serait-ce que pour ne pas avoir à redémarrer les appels systèmes
interrompus par le signal, par exemple). Dédier un thread aux signaux
est sûrement la solution la plus simple.

Le gestionnaire handler() ne semble jamais appelé (il n'imprime pas en
tout cas). Pourquoi ?


Réponse dans la doc de sigwait :

!sigwait! suspends the calling thread until one of the signals in
|set| is delivered to the calling thread. It then stores the number
of the signal received in the location pointed to by |sig| and
returns. The signals in |set| must be blocked and not ignored on
entrance to !sig_wait!. If the delivered signal has a signal
handler function attached, that function is |not| called.

Note la dernière phrase. Si vraiment c'est nécessaire, tu peux
l'appeler toi-même.

(Une remarque sur ton code : sigaction concerne le processus entier,
donc c'est un peu etrange de placer ces appels dans le corps d'un
thread. C'est un détail.)

-- Alain.

Avatar
fabrizio
05/10/2007 16:11 - Alain Ketterlin :
Réponse dans la doc de sigwait :
[...]


Ok, j'avais raté ce passage.

Merci beaucoup,
F.

Avatar
Nicolas George
fabrizio wrote in message <47063dd6$0$21884$:
g++ -o thread thread.c -lpthread


Normalement, il faut compiler avec « -pthread », et pas seulement avec
-lpthread. -pthread peut aussi ajouter des options au préprocesseur, lier
avec une autre libc (par exemple sous FreeBSOD 4), etc.

Avatar
Paul Gaborit
À (at) 05 Oct 2007 15:48:45 GMT,
Nicolas George <nicolas$ écrivait (wrote):
[...] (par exemple sous FreeBSOD 4) [...]
~~~~~~~~


J'adore cette faute de frappe ! C'est volontaire ? ;-)

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>

Avatar
Nicolas George
Paul Gaborit wrote in message :
J'adore cette faute de frappe ! C'est volontaire ? ;-)


Partiellement. Le surnom lui est venu quand je je co-administrais un parc
partiellement en FreeBSD 4 et 5, et où à cause de cette horreur de libc_r,
ainsi qu'au changement de version de la libc, mais la flemme de tout
recompiler, on avait parfois jusqu'à quatre libc différentes chargées par le
même binaire. Inutile de dire que ça ne mettait pas longtemps avant de
partir en vrille.

Avatar
Paul Gaborit
À (at) 05 Oct 2007 16:11:28 GMT,
Nicolas George <nicolas$ écrivait (wrote):
Paul Gaborit wrote in message :
J'adore cette faute de frappe ! C'est volontaire ? ;-)


Partiellement. Le surnom lui est venu quand je je co-administrais un parc
partiellement en FreeBSD 4 et 5, et où à cause de cette horreur de libc_r,
ainsi qu'au changement de version de la libc, mais la flemme de tout
recompiler, on avait parfois jusqu'à quatre libc différentes chargées par le
même binaire. Inutile de dire que ça ne mettait pas longtemps avant de
partir en vrille.


D'accord. Mais c'est moi fun !

Heureusement qu'on peut interpréter FreeBSOD dans l'autre sens : le
système qui n'a pas de BSOD ! Cela correspond beaucoup plus à mon expérience.

Mais il est vrai que je n'ai jamais tenté le passage de FreeBSD 4 à
FreeBSD 5 sur une machine. Ici, on a fait autrement : on a installé
des nouvelles machines en FreeBSD 5 puis on a peu à peu migré les
services des anciennes machines vers les nouvelles...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>