 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
kanze@gabi-soft.fr Guest
|
Posted: Thu Apr 01, 2004 7:19 am Post subject: Re: [OT] Re: parade pour ne pas ecrire une Thread |
|
|
"Arnaud Debaene" <adebaene (AT) club-internet (DOT) fr> wrote
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
C'est un peu à l'emporte pièce mais jusqu'ici j'ai peut-être vu un
ou deux endroits à tout casser où la fonction pouvait réellement
servir, et c'est dans des contextes très liés à l'OS (terminaison
de services NT en particulier).
Effectivement, ça n'a pas l'aire très utile. Mais comment faire pour
terminer un thread qui est en attente d'un évenement qui ne viendra
plus ?
On a un événement "terminer le thread", et quand le thread attend
quelque chose (appel bloquant), cet événement fait systématiquement
partie de l'ensemble des objts "signalables" sur lequel il attend.
|
Le problème se pose dans certaines fonctions de la bibliothèque. Une
fonction comme gethostbyname(), par exemple, va effectuer des lectures
sur le reseau, avec éventuellement des timeouts assez longs. Tu n'as pas
envie de le réimplémenter dans la boucle principale de ton thread,
j'imagine, et je doute forte que dans son implémentation, il ajoute ton
évenement spécial dans ses attentes.
La seule solution que je vois comme ça (sans vraiment y avoir refléchi),
c'est de définir un thread spécifique pour cette fonctionnalité ; quand
on a besoin d'appeler cette fonction, on crée un évenement qu'on envoie
à ce thread, et puis on attend la réponse dans un évenemment de rétour.
Et on écrit le thread serveur de gethostbyname d'une façon que
TerminateThread ne soit pas un problème (pas de ressourses dynamiques,
etc.). C'est un peu lourd. (En revanche, ça résoud tout problème de
thread safety associé à cette fonction -- bien que d'après la
documentation, elle est déjà thread safe sous Windows, ce qui n'est pas
le cas sous Unix.)
| Quote: | Autre solution : une APC (asynchronous procedure call). C'est un
mécanisme peu connu de Windows qui ressemble vaguement aux signaux
Unix : Quand une APC est postée à un thread, il sera exécuté par le
thread quand celui-ci sera dans un "alertable wait state" (en attente
d'événement, pour faire simple). Les drivers en mode noyau peuvent
utiliser des "kernel mode APC" qui peuvent interrompre un thread
(utilisateur ou système) n'importe quand.
|
Est-ce que l'APC interrompt une requête en cours ? C'est le cas d'un
signal Unix -- si je retourne de mon handleur de signal, une requête
bloquante éventuelle retourne avec une erreur EINTR. Dans un cas comme
gethostbyname() (en supposant que c'est bien écrit -- rien n'est moins
sûr, que ce soit windows ou que ce soit Unix), cette erreur propage
jusqu'à l'appel de la fonction. D'où je peux tester une variable
positionnée dans le signal (de type sig_atomic_t volatile, si je tiens à
la norme).
C'est une solution assez répandue, d'après ce que j'ai vu, malgré des
conditions de race.
| Quote: | C'est à peu près aussi inutilisable que le signaux sous Unix dans le
sens que la fonction est appelée hors du flux habituel du thread, et
il faut donc être extrêmement prudent sur les données que l'on
manipule dedans.
|
Typiquement, un sig_atomic_t suffit. Le problème, c'est plutôt la
condition de race : le signal n'interrompt la requête système que s'il
arrive quand on est dans la requête. Alors, même si on teste le
drappeau immédiatement avant la requête, il y a une petite fenêtre entre
le test du drappeau et l'entrée dans la requête où le signal peut
arriver sans terminer la requête (parce qu'on n'y est pas encore).
C'est le pourquoi de toutes ces complexités autours de pthread_cancel,
d'ailleurs. Un pthread_cancel, c'est un peu comme un signal qui ne peut
être pris *que* lors qu'on est dans une requête.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Thu Apr 01, 2004 7:32 am Post subject: Re: [OT] Re: parade pour ne pas ecrire une Thread |
|
|
"Arnaud Debaene" <adebaene (AT) club-internet (DOT) fr> writes:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
C'est un peu à l'emporte pièce mais jusqu'ici j'ai peut-être vu un ou
deux endroits à tout casser où la fonction pouvait réellement servir,
et c'est dans des contextes très liés à l'OS (terminaison de services
NT en particulier).
Effectivement, ça n'a pas l'aire très utile. Mais comment faire pour
terminer un thread qui est en attente d'un évenement qui ne viendra
plus ?
On a un événement "terminer le thread", et quand le thread attend quelque
chose (appel bloquant), cet événement fait systématiquement partie de
l'ensemble des objts "signalables" sur lequel il attend.
|
Donc si on a un calcul long, il faut ajouter des appels pour recuperer
cet evenement s'il a lieu. On est toujours dans l'approche ou on va
chercher l'info. Les seules methodes que je vois (sous Unix) ou on ne
vas pas chercher l'info c'est
- signaux + siglongjmp (probleme de cleanup)
- process separe + kill (cleanup uniquement par ce qui est faisable
d'un signal)
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0) +
pthread_cancel (cleanup par destructeur +
pthread_cleanup_{push/pop} + possibilite de passer en
PTHREAD_CANCEL_DEFERRED/PTHREAD_CANCEL_DISABLE pour des sections
critiques ou cancel ne doit pas etre utilise).
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Apr 02, 2004 6:34 am Post subject: Re: [OT] Re: parade pour ne pas ecrire une Thread |
|
|
Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> wrote
| Quote: | kanze (AT) gabi-soft (DOT) fr writes:
C'est le pourquoi de toutes ces complexités autours de
pthread_cancel, d'ailleurs. Un pthread_cancel, c'est un peu comme un
signal qui ne peut être pris *que* lors qu'on est dans une requête.
Ah bon?
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
Je ne parlais évidemment que du comportement par défaut. Par souci de
simplification -- comparer la cancellation d'un thread à des signaux,
c'est déjà une simplification majeur (et trompeuse, au fond).
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Apr 02, 2004 6:51 am Post subject: Re: [OT] Re: parade pour ne pas ecrire une Thread |
|
|
Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> wrote
| Quote: | Donc si on a un calcul long, il faut ajouter des appels pour recuperer
cet evenement s'il a lieu. On est toujours dans l'approche ou on va
chercher l'info. Les seules methodes que je vois (sous Unix) ou on ne
vas pas chercher l'info c'est
- signaux + siglongjmp (probleme de cleanup)
- process separe + kill (cleanup uniquement par ce qui est faisable
d'un signal)
|
En fait, une partie de l'intérêt de cette méthode, c'est le clean-up
implicit fait par le système : pas besoin de se soucier de la libération
de la mémoire, de la fermature des fichiers, etc.
En ce qui concerne le clean-up des ressources externes du processus (des
fichiers temporaires, par exemple), le processus lançant peut, dans
certains cas, s'en charger. Si c'est un fichier temporaire tout à fait
interne aux calculs, c'est moche (mais il en existe d'autres solutions,
au moins sous Unix), mais s'il s'agit du fichier où le processus de
calcul écrit ses résultats, et d'où le processus qui l'a lancé va les
lire, c'est tout à fait normal.
| Quote: | - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0) +
pthread_cancel (cleanup par destructeur +
pthread_cleanup_{push/pop} + possibilite de passer en
PTHREAD_CANCEL_DEFERRED/PTHREAD_CANCEL_DISABLE pour des sections
critiques ou cancel ne doit pas etre utilise).
|
Les options de pthread_cancel donne beaucoup de souplesse, en effet. Le
fait que certaines implémentations semblent effectuer un stack-walkback,
en appelant les destructeurs, fait qu'il convient particulièrement bien
à C++ et à l'idiome RAII.
Malheureusement, je ne crois pas qu'une solution basée sur un cancel qui
fait des stack-walkback soit très portable. Ce n'est pas qu'il y a des
différences de nom entre les fonctions Windows et Unix, ni qu'il y a de
subtiles différences dans leurs sémantiques. C'est qu'il n'y a pas du
tout de fonctionnalité équivalente sous Windows, autant que je puisse
voir. (On peut simuler des condition variables avec des sémaphores, et
vice versa, mais je ne vois pas comment implémenter quoique ce soit qui
ressemble à un cancel sous Windows.)
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|