OVH Cloud OVH Cloud

Multithreading

21 réponses
Avatar
ALB
Bonjour =E0 tous,

je n'ai jamais fait de multithreading et je cherche une r=E9f=E9rence
(anglais ou fran=E7ais) pour apprendre, qui remplirait notamment les
crit=E8res suivants :
- indique les design patterns qui passent bien (et ceux =E0 =E9viter), les
bonnes pratiques...,
- non sp=E9cifique =E0 une plateforme.

Adrien

10 réponses

1 2 3
Avatar
Luc Hermitte
the women and girls, and
exclaimed, "But if this ordinance were abolished I do not know what
would become of them." He confessed at the close of our talk that he
would like to speak freely to us about certain things connected with
the work which could not be mentioned publicly, and said there were
"perplexities--great perplexities." Yet at the beginning of the
conversation, when speaking of the criticism passed upon the
Protectorate's work, he had said, "Why do they not come here for
information instead of going about criticising? our books are all
open to public inspection." But we had noticed that throughout the
interview he kept the books in his own hands, and only allowed us to
see what he himself turned up for our inspection.

Now as to some of this official's statements--we deal with them, not
with the object of criticising his _personal_ opinions and views and
statements, but as an _official_ representation to us of a Government
institution.

To begin with, he had told us two absolute falsehoods, at least. One
was that there was no Lock Hospital at Singapore, whereas we had
visited this Government institution and by careful inspection found it
was used for _the one purpose only_, having no equipment for any other
uses, and there were fifteen prostitutes there. When confronted with
this knowledge, which, remembering our hostess' caution as to his
temper, we expressed as gently as possible, he then declared it was
a general hospital, which it was not. He declared there were no
compulsory examinations, and that the Government had nothing to do
with examinations in any form. We thought it wisest not to give him
the information that we held at that time, and hold to the present
day,--dozens of papers of committment to the Lock Hospital for
compulsory examinations both in his own handwriting and in that of
the Protector. And some of these cases, as the records we have copied
show, were those of perfectly inno
Avatar
James Kanze
On Jan 21, 11:24 pm, Loïc Joly
wrote:
- Les threads pour faire plus de choses en même temps.



Est-ce que tu veux dire : pour pouvoir interrompre une activité
pour en traiter quelque chose de plus importante ? Genre,
remettre à jour la graphique, bien qu'il y ait un calcul
important qui n'a pas fini.


Oui. Dit autrement, des threads pour la réactivité, plus que pour les
performances.


Voilà le mot que je cherchais : réactivitité.

Les threads pour faire plus en même temps me semblent déjà bien p lus
structurant au niveau du programme, font souvent tourner une boucle dan s
leur fonction principale, avec ou sans timer,...


Je ne suis pas sûr que je comprends.


Je voulais dire par là que souvent, ce genre de thread a une
durée de vie (et des responsabilités) plus grande que cette
d'un thread pour les performances. Et ces threads n'ont pas un
début et une fin intrinsèques, mais tournent en boucle jusqu'à
ce qu'on leur demande d'arrêter.


D'accord. Un thread serveur qui s'active lors d'une connexion,
et qui reste actif tant que la connexion est établie, par
exemple.

C'est un exemple type (au moins dans mes applications) d'un
thread détaché. « Fire and forget », comme on dit en anglais.
(Ce qui n'est pas forcement complètement le cas ; on pourrait
vouloir savoir de son existence pour effectuer un arrêt de
système propre, par exemple.)

Mais les threads worker dans une interface graphique sont
souvent de la même nature (sauf en ce qui concerne leur durée de
vie). La fonction qui les lance ne peut pas les attendre, en
faisant un join, parce qu'il faut que le thread où il tourne
soit réactif. Alors, c'est au thread worker de s'arranger pour
que le résultat de son travail s'affiche.

Et dans certains domaines, liés au temps réel entre autre,
certains de ces threads ont une durée de vie égale à celle du
programme, et des contraites en qualité de cadencement qui
leur sont propres.


Le vrai temps réel, c'est encore un domain en soi. En
particulier, on doit pouvoir affecter des priorités aux threads,
de façon à ce que le thread important ait la CPU s'il en a
besoin.

Il est pour moi assez différent de dire que le calcul sera
dans un thread à part pour que l'affichage continue à se
raffraichir (et les contraintes de qualité s'exprimeront le
plus souvent en temps maximum avant le réveil du thread), et
que dire que la mise en forme et l'envoi d'information à tel
actionneur s'effectuera dans un thread à part, cadencé à 30ms
+/- 1ms.

Cette notion de thread cadencée, aujourd'hui, je l'effectue en
ayant simplement un thread qui boucle avec une attente sur un
timer, mais je me demande si c'est vraiment le bon modèle.


Ça dépend de la fréquence, et encore pas mal d'autres choses.
Cadencé à moins de quelques centaines de millisecondes, j'ai mes
doutes sur des systèmes courants. Mais si tu travailles au
niveau application sous Unix ou sous Windows, je ne sais pas si
on peut faire mieux.

Plusieurs points quand même :

-- Il faut que l'attente soit sur une heure précise, et non sur
un intervale, pour ne pas varier avec le temps d'exécution
de la tâche, voire même les aléas dans l'activation. Sous
Unix, par exemple, j'utiliserais pthread_cond_timedwait(),
plutôt que nanosleep() ou la classique poll().

-- Si c'est important que la tâche soit activée autant de fois
que l'intervale s'écroule, on pourrait considérer un thread
tout simple qui ne fait qu'attendre l'intervale, puis poster
un évenemment dans une queue. Le thread qui effectue
l'action attend sur la queue -- si pour une raison
quelconque, il prend une fois trop de temps, il y aura
simplement deux entrées dans la queue. (S'il prend
systèmatiquement trop de temps, évidemment, ce n'est pas une
solution.)

Dans les applications temps réel, d'ailleurs, ce n'est pas
rare d'avoir un thread dédié à la gestion de telles
attentes.

Dans les deux cas, le réveil du thread s'effectue par un
évènement (mouvement souris ou timer), mais il y a
suffisemment de différences entre les deux cas pour que je
veuille les séparer (par exemple la gestion de ce qui se passe
quand l'évènement est réémis alors que le traitement précédent
n'a pas eu le temps de se terminer).


Certainement.

Finalement, j'en arrive à la classification suivante :

- Thread pour la performance


Mot clé : parallelisation.

- Thread pour la réactivité
- Cadencé
- Réveillé par des évènements autres


D'un certain côté, je distinguerais entre la réactivité
proprement dite, comme les thread worker dans une interface
graphique, et les threads qui servent surtout à gérer un
contexte, par exemple des threads qui gèrent les connexions
client dans un serveur. La réactivité joue bien un rôle dans ces
derniers, mais on utilise des threads surtout pour ne pas avoir
à stocker explicitement la contexte ou l'état de chaque
connexion -- il se trouve implicitement sur la pile du thread.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34




Avatar
Luc Hermitte
On 21 jan, 15:00, James Kanze wrote:
On Jan 21, 11:16 am, Luc Hermitte wrote:

On 18 jan, 09:29, James Kanze wrote:
[...] et ne s'adresse pas à
des questions plus élevées, du genre des modèles de conception à
utiliser en C++. Il y a effectivement un trou entre lui et des
livres de conception C++, et je ne connais rien qui s'y
position.
Dans une certaine mesure, il y a les bouquins et articles de Schmidt,

non? Ils sont très orientés patterns avec pour exemple
d'implémentation sa bibliothèque, ACE -- dont je te sais peu
partisant.


Je sais qu'il en a écrit. Je ne sais pas trop ce qu'ils
valent ; quand j'ai essayé d'utiliser ACE, j'en étais très
deçu, aussi bien côté qualité que côté utilisabilité.


J'ai pas mal utilisé ACE ces derniers temps. J'apprécie la richesse
des patterns, mais parfois l'utilisabilité, pour reprendre tes mots,
laisse effectivement à désirer. :(
Seulement, je ne connais pas d'autre bibliothèque qui fournisse autant
de choses -- en plus des contraintes projet qui fait que ACE restera
où il est pendant des années encore.

Un livre, par exemple, qui expliquerait les
différentes façons d'organiser les threads en classes. (J'en
connais trois ou quatre, dont la plus répandue est à mon avis à
éviter.)
Ta parenthèse m'interresse. Tu pourrais développer STP (un lien ou u n

nom m'irait).


Malheureusement, ce sont des choses que j'ai appris par ci, par
là, sans vraiment savoir où. Un modèle, c'est évident : c'est
celui de ACE, qui est aussi plus ou moins celui de Java -- 'est
grosso mode l'utilisation du modèle du méthode template pour la
class Thread, avec customisation par dérivation pour la fonction
à exécuter dans le thread.


ACE ne propose pas que ce modèle (on a aussi des threads fonction, les
futures, ...). Mais j'avoue que c'est celui d'ACE que j'utilise
majoritairement, voire exclusivement. En grande partie parce que les
ACE_Task intègrent des messages blocks -- cf plus bas.

C-à-d state of the art il y a quinze
ans, mais avec des problèmes bien connus entre temps. (Java
l'étend en offrant l'option entre le modèle du méthode template
et le modèle stratégie, avec customisation par un délégué. Entre
temps, il est fortement conseillé d'utiliser le délégué.)


OK, je vais voir à trouver des références au sujet de ces problèmes
introduits. Merci.



Ni des modèles de communication entre les threads --
comment implémenter un queue de messages, par exemple. (Dans mon
cas, par exemple, j'ai choisi d'utiser auto_ptr au niveau de
l'interface -- une fois l'objet passé à l'autre thread, le
thread émitteur n'en a plus accès.)
Mais, cela ne résout pas le cas où il faut passer le message à

plusieurs threads.


Dans quel sens ?
[...]
-- En revanche, il n'est pas conçu pour une emission
« broadcast ». Chose dont je n'avais pas besoin, mais qui
pourrait sans doute être utile dans d'autres applications.
(A priori, dans de tels cas, je préfèrerais un passage par
copie, de façon à ce que chaque thread ait sa propre copie
privée du message.)


Celui-ci. Je l'utilise dans une application de type routeur qui
redonde une télémétrie entrante vers plusieurs canaux en sortie. Les
trames pouvant varier entre une vingtaine d'octets et quelques
dizaines de kilo-octets, la solution retenue est celle d'ACE qui offre
un comptage de référence (avec compteur atomique si mes souvenirs sont
bons)



(c'est pénible ces spams qui usurpent nos identités)
--
Luc Hermitte



Avatar
Laurent Deniau
On 22 jan, 11:09, James Kanze wrote:
On Jan 21, 11:24 pm, Loïc Joly
wrote:

- Les threads pour faire plus de choses en même temps.
Est-ce que tu veux dire : pour pouvoir interrompre une activité


pour en traiter quelque chose de plus importante ? Genre,
remettre à jour la graphique, bien qu'il y ait un calcul
important qui n'a pas fini.
Oui. Dit autrement, des threads pour la réactivité, plus que pour le s

performances.


Voilà le mot que je cherchais : réactivitité.


Les termes generalement utilises dans la litterature sont
'concurrence' (reactivite) et 'parallelisme' (performance).

a+, ld.





Avatar
Michael DOUBEZ
On 21 jan, 15:00, James Kanze wrote:
On Jan 21, 11:16 am, Luc Hermitte wrote:

On 18 jan, 09:29, James Kanze wrote:
[...] et ne s'adresse pas à
des questions plus élevées, du genre des modèles de conception à
utiliser en C++. Il y a effectivement un trou entre lui et des
livres de conception C++, et je ne connais rien qui s'y
position.
Dans une certaine mesure, il y a les bouquins et articles de Schmidt,

non? Ils sont très orientés patterns avec pour exemple
d'implémentation sa bibliothèque, ACE -- dont je te sais peu
partisant.
Je sais qu'il en a écrit. Je ne sais pas trop ce qu'ils

valent ; quand j'ai essayé d'utiliser ACE, j'en étais très
deçu, aussi bien côté qualité que côté utilisabilité.


J'ai pas mal utilisé ACE ces derniers temps. J'apprécie la richesse
des patterns, mais parfois l'utilisabilité, pour reprendre tes mots,
laisse effectivement à désirer. :(


Ca et les noms à rallonge pré-namespace plus toutes les macros faites
pour supporter différents compilateur. C'est quasiment impossible à
décorer par un template utilisateur.

Seulement, je ne connais pas d'autre bibliothèque qui fournisse autant
de choses -- en plus des contraintes projet qui fait que ACE restera
où il est pendant des années encore.


J'ai entendu du bien de Poco. Je ne l'ai pas encore testée.
http://pocoproject.org/poco/info/index.html


Un livre, par exemple, qui expliquerait les
différentes façons d'organiser les threads en classes. (J'en
connais trois ou quatre, dont la plus répandue est à mon avis à
éviter.)
Ta parenthèse m'interresse. Tu pourrais développer STP (un lien ou un

nom m'irait).
Malheureusement, ce sont des choses que j'ai appris par ci, par

là, sans vraiment savoir où. Un modèle, c'est évident : c'est
celui de ACE, qui est aussi plus ou moins celui de Java -- 'est
grosso mode l'utilisation du modèle du méthode template pour la
class Thread, avec customisation par dérivation pour la fonction
à exécuter dans le thread.


ACE ne propose pas que ce modèle (on a aussi des threads fonction, les
futures, ...). Mais j'avoue que c'est celui d'ACE que j'utilise
majoritairement, voire exclusivement. En grande partie parce que les
ACE_Task intègrent des messages blocks -- cf plus bas.

C-à-d state of the art il y a quinze
ans, mais avec des problèmes bien connus entre temps. (Java
l'étend en offrant l'option entre le modèle du méthode template
et le modèle stratégie, avec customisation par un délégué. Entre
temps, il est fortement conseillé d'utiliser le délégué.)


OK, je vais voir à trouver des références au sujet de ces problèmes
introduits. Merci.


J'utilise un système du genre:
template<typename T_FUNCTOR>
class CMessageTask: public ACE_Task<ACE_MT_SYNCH>
{
public:
typedef ACE_Task <ACE_MT_SYNCH> inherited;

CMessageTask(const T_FUNCTOR& fun, size_t n_threads=1):
n_threads_(n_threads),functor_(fun)
{}

...
};

Avec un appel au functor dans la boucle svc avec en paramètre les
messages. Mes fonction open() et close() gèrent l'activation et l'arrèt
du thread avec un système de protocole (message HANGUP).

Ensuite, c'est facile de fournir un functor ou même Boost.Function:
CMessageTask<boost::fonction1<void,ACE_Message_Block*> >





Ni des modèles de communication entre les threads --
comment implémenter un queue de messages, par exemple. (Dans mon
cas, par exemple, j'ai choisi d'utiser auto_ptr au niveau de
l'interface -- une fois l'objet passé à l'autre thread, le
thread émitteur n'en a plus accès.)
Mais, cela ne résout pas le cas où il faut passer le message à

plusieurs threads.
Dans quel sens ?

[...]
-- En revanche, il n'est pas conçu pour une emission
« broadcast ». Chose dont je n'avais pas besoin, mais qui
pourrait sans doute être utile dans d'autres applications.
(A priori, dans de tels cas, je préfèrerais un passage par
copie, de façon à ce que chaque thread ait sa propre copie
privée du message.)



J'ai eu le même problème. Si quelqu'un a une solution élégante et
extensibe, je suis preneur (à part en utilisant des sockets locales en
mode datagramme).


Celui-ci. Je l'utilise dans une application de type routeur qui
redonde une télémétrie entrante vers plusieurs canaux en sortie. Les
trames pouvant varier entre une vingtaine d'octets et quelques
dizaines de kilo-octets, la solution retenue est celle d'ACE qui offre
un comptage de référence (avec compteur atomique si mes souvenirs sont
bons)


J'ai une appli du même genre et la copie par référence m'a sauvé pas mal
de mips (comparé à un ancien système maison inspiré de ACE).

Michael




Avatar
James Kanze
On Jan 22, 11:22 am, Laurent Deniau wrote:
On 22 jan, 11:09, James Kanze wrote:

On Jan 21, 11:24 pm, Loïc Joly
wrote:

- Les threads pour faire plus de choses en même temps.
Est-ce que tu veux dire : pour pouvoir interrompre une activité


pour en traiter quelque chose de plus importante ? Genre,
remettre à jour la graphique, bien qu'il y ait un calcul
important qui n'a pas fini.
Oui. Dit autrement, des threads pour la réactivité, plus que pour les

performances.


Voilà le mot que je cherchais : réactivitité.


Les termes generalement utilises dans la litterature sont
'concurrence' (reactivite) et 'parallelisme' (performance).


Parallelisme pour la performance, je sais. Mais j'aurais compris
quelque chose de plus général par concurrence (peut-être
influencé par ma compréhension de « concurrency » en anglais).
Sous concurrence, j'aurais entendu et le parallelisme, et la
réactivité.

L'idée (pas forcément technique) que je cherchais, évidemment,
c'est que le processus puisse réagir à des évenemments externes
bien qu'il soit en plein milieu d'un traitement assez long.

Et comme j'ai expliqué par la suite, il y a des utilisations où
ni la réactivité ni le parallelisme sont réelement motivant. Où
la véritable motivation, c'est simplement d'avoir un contexte
séparé, géré automatiquement (donc, la pile implicite avec des
variables locales et un pointeur d'instructions, plutôt qu'un
objet avec un tas d'états explicit).

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34






Avatar
James Kanze
On Jan 22, 11:10 am, Luc Hermitte wrote:
On 21 jan, 15:00, James Kanze wrote:



On Jan 21, 11:16 am, Luc Hermitte wrote:

On 18 jan, 09:29, James Kanze wrote:
[...] et ne s'adresse pas à
des questions plus élevées, du genre des modèles de conception à
utiliser en C++. Il y a effectivement un trou entre lui et des
livres de conception C++, et je ne connais rien qui s'y
position.
Dans une certaine mesure, il y a les bouquins et articles de Schmidt,

non? Ils sont très orientés patterns avec pour exemple
d'implémentation sa bibliothèque, ACE -- dont je te sais peu
partisant.


Je sais qu'il en a écrit. Je ne sais pas trop ce qu'ils
valent ; quand j'ai essayé d'utiliser ACE, j'en étais très
deçu, aussi bien côté qualité que côté utilisabilité.


J'ai pas mal utilisé ACE ces derniers temps. J'apprécie la richesse
des patterns, mais parfois l'utilisabilité, pour reprendre tes mots,
laisse effectivement à désirer. :(


J'avoue ne l'avoir évalué que dans le contexte d'un seul projet.
Des essais rapide ont démontré une complexité énorme pour
resoudre un problème en somme tout assez simple (un protocol
UDP). Et des erreurs assez genantes.

Seulement, je ne connais pas d'autre bibliothèque qui
fournisse autant de choses


Il faut peut-être un melange des bibliothèques:-).

-- en plus des contraintes projet
qui fait que ACE restera où il est pendant des années encore.

Un livre, par exemple, qui expliquerait les
différentes façons d'organiser les threads en classes. (J'en
connais trois ou quatre, dont la plus répandue est à mon avis à
éviter.)
Ta parenthèse m'interresse. Tu pourrais développer STP (un lien ou un

nom m'irait).


Malheureusement, ce sont des choses que j'ai appris par ci, par
là, sans vraiment savoir où. Un modèle, c'est évident : c'est
celui de ACE, qui est aussi plus ou moins celui de Java -- 'est
grosso mode l'utilisation du modèle du méthode template pour la
class Thread, avec customisation par dérivation pour la fonction
à exécuter dans le thread.


ACE ne propose pas que ce modèle (on a aussi des threads fonction, les
futures, ...). Mais j'avoue que c'est celui d'ACE que j'utilise
majoritairement, voire exclusivement. En grande partie parce que les
ACE_Task intègrent des messages blocks -- cf plus bas.

C-à-d state of the art il y a quinze
ans, mais avec des problèmes bien connus entre temps. (Java
l'étend en offrant l'option entre le modèle du méthode template
et le modèle stratégie, avec customisation par un délégué. Ent re
temps, il est fortement conseillé d'utiliser le délégué.)


OK, je vais voir à trouver des références au sujet de ces problème s
introduits. Merci.


Le problème est simple. Si on démarre le thread dans le
constructeur (comme fait Java), il risque de démarrer avant que
le constructeur de la classe dérivée ait fini.

[...]
(c'est pénible ces spams qui usurpent nos identités)



N'est-ce pas ? Mais je crains qu'il n'y a rien à faire, au moins
pas sans un effort démesuré.

--
James Kanze (GABI Software) mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34




Avatar
Fabien LE LEZ
On Tue, 22 Jan 2008 06:57:54 -0800 (PST), James Kanze
:

(c'est pénible ces spams qui usurpent nos identités)


N'est-ce pas ? Mais je crains qu'il n'y a rien à faire, au moins
pas sans un effort démesuré.


Étant donné que je n'ai pas vu ces spams, je ne peux que conseiller
d'utiliser news.free.fr, serveur décent aux règles de filtrage
manifestement efficaces. (Bien entendu, si je me permets de le
conseiller, c'est parce que tout résident français peut obtenir un
accès gratuitement.)


Avatar
Luc Hermitte
<HS>
On 22 jan, 16:13, Fabien LE LEZ wrote:
On Tue, 22 Jan 2008 06:57:54 -0800 (PST), James Kanze
:

(c'est pénible ces spams qui usurpent nos identités)


N'est-ce pas ? Mais je crains qu'il n'y a rien à faire, au moins
pas sans un effort démesuré.


Étant donné que je n'ai pas vu ces spams, je ne peux que conseiller
d'utiliser news.free.fr, serveur décent aux règles de filtrage
manifestement efficaces. (Bien entendu, si je me permets de le
conseiller, c'est parce que tout résident français peut obtenir un
accès gratuitement.)


Ouais. Sauf la journée où je passe par googlegroups pour venir et ici
-- pas de NNTP possible avec nos proxies. Et pas toujours la nuit où
mon free en ReADSL ne me permet même pas toujours de pouvoir consulter
mes mails
:'-(
</HS>

--
Luc Hermitte



Avatar
Luc Hermitte
On 22 jan, 15:57, James Kanze wrote:
On Jan 22, 11:10 am, Luc Hermitte wrote:
[...] l'utilisation du modèle du méthode template pour la
class Thread, avec customisation par dérivation pour la fonction
à exécuter dans le thread.
[...]



C-à-d state of the art il y a quinze
ans, mais avec des problèmes bien connus entre temps. (Java
l'étend en offrant l'option entre le modèle du méthode template
et le modèle stratégie, avec customisation par un délégué. E ntre
temps, il est fortement conseillé d'utiliser le délégué.)
OK, je vais voir à trouver des références au sujet de ces problè mes

introduits. Merci.


Le problème est simple. Si on démarre le thread dans le
constructeur (comme fait Java), il risque de démarrer avant que
le constructeur de la classe dérivée ait fini.


Cela ne m'a pas choqué. Probablement car on est poussés à construire
diverses choses, puis initialiser dans open(), puis à activer avec une
fonction externe.
Il est vrai que l'on peut mieux faire. Le "delete this" pour lequel je
m'étais résigné me perturbait limite plus.



1 2 3