OVH Cloud OVH Cloud

mise a jour d'une liste de threads

73 réponses
Avatar
luc2
j'ai plusieurs threads qui tournent. chaque thread est un objet. dans
le programme principal, j'ai une liste de tous ces threads (dans un
tableau par exemple).

supposons qu'un thread se termine. comment peut-il prevenir le
programme principal, afin qu'il enleve sa reference de la liste de
threads ?

solution 1 (mauvaise) : le thread a une reference vers la liste, et il
peut la modifier. or, cela est absurde en programmation objet; le
thread (qui est un objet) n'a pas a contenir une reference vers la
liste.

solution 2 (mauvaise) : la liste est une variable globale. le thread
peut donc y avoir acces. or, une fois de plus, cela est absurde en
programmation objet; le thread n'a pas a s'occuper de mettre la liste
de threads a jour. il n'est meme pas cense savoir qu'il est repertorie
dans une liste.

existe-t-il une solution propre et non-marginale a ce probleme de
conception objet ?

10 réponses

1 2 3 4 5
Avatar
Falk Tannhäuser
luc2 wrote:
On Mon, 10 Jan 2005 22:45:16 +0100, James Kanze wrote:
supposons qu'un thread se termine. comment peut-il prevenir le
programme principal, afin qu'il enleve sa reference de la
liste de threads ?

solution 1 (mauvaise) : le thread a une reference vers la
liste, et il peut la modifier. or, cela est absurde en
programmation objet; le thread (qui est un objet) n'a pas a
contenir une reference vers la liste.


Pourquoi pas ? C'est justement parce que c'est un objet qu'il
peut s'inscrire et se désinscrire dans d'autres objets.


mais il ne DOIT PAS etre prevu pour s'inscrire et se desinscrire des
autres objets. un objet coherent n'a pas a savoir par qui il est
reference.


La solution à ce dilemme en POO me paraît archi-classique :
Quand on veux casser une dépendance circulaire, on introduit
une classe de base (typiquement abstraite) supplémentaire,
et on fait dépendre les deux "participants au cycle" de cette
classe, au lieu d'avoir une dépendance mutuelle directe entre
eux...

Ici, par exemple, on pourrait avoir une ABC "ThreadObserver"
avec des fonction membres virtuelles pures "Notify_started()"
et "Notify_terminated()" ;
chaque "Thread" comporte soit un pointeur sur "ThreadObserver"
(relation à cardinalité 0..1), soit un conteneur de pointeurs
(délation 0..n).
La classe "ThreadList" dérive de "ThreadObserver" et implémente
les fonctions mentionnées ci-dessus. Ainsi, un "Thread" n'a pas
à savoir qu'il appartient à une liste où il faut s'inscrire ou
désinscrire, il connaît uniquement l'interface définie par
"ThreadObserver".

Falk



Avatar
luc2
On 11 Jan 2005 00:43:19 -0800, wrote:

ma question n'a pas l'air de vous inspirer. je vais vous
donner un exemple de solution en java :

on donne un listener au thread pour qu'il nous previenne quand
il se termine. quand le listener se declenche, il met la liste
de threads a jour. c'est tout.


Je n'ai pas trouvé ça dans Java. Il n'y a aucun Listener pour
quoique ce soit des Threads.


ce que tu viens d'ecrire confirme ce que je pensais : tu es loin de la
programmation objet, et surtout, loin de l'esprit de conception.

la question que j'ai pose est une question de CONCEPTION. je peux donc
CONCEVOIR mes classes comme je le veux. si j'ai besoin que le thread
puisse accepter un listener, alors je le CONCOIS comme tel.

La plupart des classes Thread que j'ai vu en C++ ont bien une
fonction statique pour obtenir la liste des threads actifs. En
Java, il y a une liste par ThreadGroup, plutôt qu'une liste
globale pour tout le monde ; ce n'est donc pas une fonction
statique, mais sinon, c'est le même principe.


le threadgroup ne change rien au probleme. tu peux stocker la liste de
threads avec un tableau, un vecteur, une liste, un ensemble ou un
threadgroup, c'est pareil; la question est de savoir COMMENT mettre le
tableau, le vecteur, la liste, l'ensemble ou le threadgroup a jour.

les listeners sont couramment utilises en java. c'est donc une
solution propre et non-marginale. de plus, elle respecte les
principes de la programmation objet.


Le fait d'utiliser les listeners n'a rien à voir avec le
langage. C'était courant en C++ avant même que le Java existait,
et courant en Smalltalk avant que le C++ ait vu le jour.


je crois que tu confonds "etre courant" et "exister". les listeners
existent en c++, mais ils ne sont pas courants. demande a un
programmeur de c++ s'il sait ce qu'est un listener, il ne saura pas,
il n'en aura jamais utilise, tandis qu'en java, il y a cent chances
sur cent qu'il sache ce que c'est.

en java, il est evident que les listeners sont courants : il y en a
partout dans l'api du java. on est donc obliges de s'en servir.

d'autre part, je m'etonne qu'il n'y ait pas d'autre solution que de
faire un listener pour resoudre le probleme.

Évidemment, il ne sont pas utilisé dans tous les programmes ; on
s'en sert (ou en Java ou en C++) que dans les cas où la solution
convient. (Si on trouve qu'ils sont plus fréquents en Java,
c'est peut-être que...


je t'interromps ici. tu es sur le point d'expliquer POURQUOI les
listeners sont plus frequents en java. or, ON N'A PAS BESOIN de savoir
pourquoi. ton explication est donc hors-sujet.

le fait est la : les listeners SONT plus frequents en java. donc, ca
ne me derange pas d'utiliser cette solution en java. les listeners NE
SONT PAS frequents en c++, donc, ca me derange d'utiliser cette
solution en c++.

les listeners ne sont pas courants en c++.


Ça dépend du domaine d'application. Ils sont très courants où
ils conviennent.


je ne suis pas en train de me restreindre a un domaine quelconque. je
dis qu'en GENERAL (c'est-a-dire a partir d'une vision GLOBALE de tous
les domaines), les listeners ne sont pas courants en c++.

maintenant que vous avez eu un exemple de ce que j'attendais
comme solution, ce sera de la rigolade pour vous d'y repondre.


Mais si tu sais ce que tu veux comme solution, pourquoi la
question ?


parce que ma solution concerne le java, pas le c++.

Si tu veux un listener sur la fin d'un Thread, c'est
assez facile à implémenter. L'avantage que les Thread ne font
pas partie de la bibliothèque standard, c'est que tu peux les
implémenter comme tu veux. (Le désavantage, évidemment, c'est
qu'il faut les implémenter, et que chacun les implémente un peu
différemment.)


je n'ai pas demande une solution quelconque. j'ai demande une solution
propre et non-marginale. si les listeners ne sont pas courants en c++,
alors la solution des listeners est marginale en c++.


Avatar
Christophe Lephay
"luc2" a écrit dans le message de news:

On 11 Jan 2005 00:43:19 -0800, wrote:
ce que tu viens d'ecrire confirme ce que je pensais : tu es loin de la
programmation objet, et surtout, loin de l'esprit de conception.


Je pense que tu n'as pas compris le sens d'une des réponse de Jean-Marc. La
POO ne fait pas l'objet d'une idéologie sacrée sur ce groupe. Si tu
souhaites une discussion politique ou idéologique, il y en a qui sont plus
approprié que celui-ci qui a plutôt une vocation technique.

la question que j'ai pose est une question de CONCEPTION. je peux donc
CONCEVOIR mes classes comme je le veux. si j'ai besoin que le thread
puisse accepter un listener, alors je le CONCOIS comme tel.


Non. Tu ne peux pas nécessairement les concevoir comme tu veux car il se
peut qu'elles soient amenées à collaborer avec un cadre pré-existant, que ce
soit des bibliothèques ou frameworks tierces ou une api spécifique imposée
par ton système d'exploitation.

le threadgroup ne change rien au probleme. tu peux stocker la liste de
threads avec un tableau, un vecteur, une liste, un ensemble ou un
threadgroup, c'est pareil; la question est de savoir COMMENT mettre le
tableau, le vecteur, la liste, l'ensemble ou le threadgroup a jour.


La question pour toi, à ce qu'il semble, consiste plus à savoir comment le
faire tout en respectant une conception idéologique de la POO.

les listeners sont couramment utilises en java. c'est donc une
solution propre et non-marginale. de plus, elle respecte les
principes de la programmation objet.


Le fait d'utiliser les listeners n'a rien à voir avec le
langage. C'était courant en C++ avant même que le Java existait,
et courant en Smalltalk avant que le C++ ait vu le jour.



Celà devient dépendant du langage dès que c'est le langage qui définit l'api
avec le système d'exploitation.

je crois que tu confonds "etre courant" et "exister". les listeners
existent en c++, mais ils ne sont pas courants. demande a un
programmeur de c++ s'il sait ce qu'est un listener, il ne saura pas,
il n'en aura jamais utilise, tandis qu'en java, il y a cent chances
sur cent qu'il sache ce que c'est.


Parce que les listeners font partie de l'api de java et ne sont pas dans ces
cas précis un simple choix de conception de la part du programmeur.

en java, il est evident que les listeners sont courants : il y en a
partout dans l'api du java. on est donc obliges de s'en servir.


Donc on est d'accord que c'est quelque chose qui a à voir avec le langage,
contrairement à ce que tu affirmes quelques paragraphes au dessus.

d'autre part, je m'etonne qu'il n'y ait pas d'autre solution que de
faire un listener pour resoudre le probleme.


Il y a bien d'autres solutions, il se trouve juste qu'on se facilite
généralement la vie en centralisant les diverses responsabilités.

Évidemment, il ne sont pas utilisé dans tous les programmes ; on
s'en sert (ou en Java ou en C++) que dans les cas où la solution
convient. (Si on trouve qu'ils sont plus fréquents en Java,
c'est peut-être que...


je t'interromps ici. tu es sur le point d'expliquer POURQUOI les
listeners sont plus frequents en java. or, ON N'A PAS BESOIN de savoir
pourquoi. ton explication est donc hors-sujet.


Si ce n'est que la raison pour laquelle ils sont frequents en Java
s'applique aussi, peut-être bien, à un autre langage.

le fait est la : les listeners SONT plus frequents en java. donc, ca
ne me derange pas d'utiliser cette solution en java. les listeners NE
SONT PAS frequents en c++, donc, ca me derange d'utiliser cette
solution en c++.


Ne sont pas fréquents en C++ ? C'est dans quel verset de ta bible ?

les listeners ne sont pas courants en c++.


Ça dépend du domaine d'application. Ils sont très courants où
ils conviennent.


je ne suis pas en train de me restreindre a un domaine quelconque. je
dis qu'en GENERAL (c'est-a-dire a partir d'une vision GLOBALE de tous
les domaines), les listeners ne sont pas courants en c++.


Il n'y a rien de général. tout dépend du type d'application que tu crées.
S'il y a moins *en général* de listeners en C++ qu'en Java (ce qui reste à
démontrer), c'est que les applications cibles en ont moins besoin *en
général*.

maintenant que vous avez eu un exemple de ce que j'attendais
comme solution, ce sera de la rigolade pour vous d'y repondre.


Mais si tu sais ce que tu veux comme solution, pourquoi la
question ?


parce que ma solution concerne le java, pas le c++.


Et pourquoi une solution adoptée dans un langage ferait qu'elle ne peut pas
l'être dans un autre ?

je n'ai pas demande une solution quelconque. j'ai demande une solution
propre et non-marginale. si les listeners ne sont pas courants en c++,
alors la solution des listeners est marginale en c++.


Comme il a été dit, les listeners ne sont pas "marginaux" en C++. Ils sont
une solution classique, idiomatique en POO en général et en C++ en
particulier (connu sous le pattern qui t'a été indiqué, et qui est catalogué
comme un pattern précisément parce que c'est une solution courante).

Bon. visiblement, il n'y a pas grand chose à espérer d'une discussion avec
toi, et je m'en tiendrai donc là.



Avatar
luc2
On Tue, 11 Jan 2005 13:40:56 +0100, "Christophe Lephay"
wrote:

Pourquoi pas ? C'est justement parce que c'est un objet qu'il
peut s'inscrire et se désinscrire dans d'autres objets.


mais il ne DOIT PAS etre prevu pour s'inscrire et se desinscrire des
autres objets. un objet coherent n'a pas a savoir par qui il est
reference.


Mais en pratique, un objet est rarement "cohérent" *par lui-même*.


c'est qu'il est mal concu.

La
finalité d'un objet, c'est assez souvent de collaborer avec d'autres objets.
D'une manière ou d'une autre, le listener doit bien être tenu informé des
objets qu'il écoute. Soit il les créera ou les détruira de lui-même, auquel
cas l'objet lui-même n'aura pas besoin de s'inscrire et se désinscrire, soit
la création de l'objet se fait via une api qui echape au listener, auquel
cas ce sera à l'objet écouté de s'enregistrer/désenregistrer.


je ne vois pas ou tu veux en venir. quelle est la bonne solution ?
quelle est la mauvaise ? c'est le listener qui doit desinscrire
l'objet ? ou c'est l'objet lui-meme ?

La cohérence, ça consiste avant tout à trouver une solution qui fournisse la
fonctionnalité attendue en fonction des différentes contraintes de
l'environnement.


c'est une autre coherence dont tu parles la. moi, je parlais de la
coherence par rapport a la programmation objet.



Avatar
Christophe Lephay
"luc2" a écrit dans le message de news:

On Tue, 11 Jan 2005 13:40:56 +0100, "Christophe Lephay"
wrote:
Mais en pratique, un objet est rarement "cohérent" *par lui-même*.


c'est qu'il est mal concu.


Non. L'objectif dans un système objet n'est pas d'avoir des objets autonomes
mais de les faire communiquer entre eux.

La
finalité d'un objet, c'est assez souvent de collaborer avec d'autres
objets.
D'une manière ou d'une autre, le listener doit bien être tenu informé des
objets qu'il écoute. Soit il les créera ou les détruira de lui-même,
auquel
cas l'objet lui-même n'aura pas besoin de s'inscrire et se désinscrire,
soit
la création de l'objet se fait via une api qui echape au listener, auquel
cas ce sera à l'objet écouté de s'enregistrer/désenregistrer.


je ne vois pas ou tu veux en venir. quelle est la bonne solution ?
quelle est la mauvaise ? c'est le listener qui doit desinscrire
l'objet ? ou c'est l'objet lui-meme ?


La bonne ou mauvaise solution dépendra de contraintes spécifiques au cas par
cas. L'objectif finale est que la procédure
d'enregistrement/désenregistrement soit fiable, si possible automatique. Il
n'y a pas une façon unique d'atteindre ce but en C++. Il se peut aussi que
différentes solutions se valent ou aient chacunes leurs avantages et
inconvénients au cas par cas (pourrait-on réellement parler de choix de
design dans le cas contraire ?).

La cohérence, ça consiste avant tout à trouver une solution qui fournisse
la
fonctionnalité attendue en fonction des différentes contraintes de
l'environnement.


c'est une autre coherence dont tu parles la. moi, je parlais de la
coherence par rapport a la programmation objet.


Et quels sont ces critères de cohérence selon toi ? La finalité n'est pas la
POO mais quelque chose d'autre que la POO elle-même tete d'atteindre. Le
sage montre la lune et le fou regarde le doigt, comme dirait l'autre. La POO
n'est pas une fin mais un moyen.


Avatar
no.bcausse.spam
luc2 wrote:

cette solution n'est pas propre. en effet, la liste ne sera pas
toujours a jour. elle ne le sera que periodiquement.


pourquoi?
avant de lui demandé quelque chose tu la mets a jour ("manuellement") et
de tout facon comment peux tu etre sur que pendant ta demande un thread
ne se termine pas. un thread c'est paralelle par definition.
--
bruno Causse
http://perso.wanadoo.fr/othello

Avatar
luc2
On 11 Jan 2005 14:08:47 +0100, Jean-Marc Bourguet
wrote:

j'ai plusieurs threads qui tournent. chaque thread est un
objet. dans le programme principal, j'ai une liste de tous ces
threads (dans un tableau par exemple).

supposons qu'un thread se termine. comment peut-il prevenir le
programme principal, afin qu'il enleve sa reference de la
liste de threads ?

solution 1 (mauvaise) : le thread a une reference vers la
liste, et il peut la modifier. or, cela est absurde en
programmation objet; le thread (qui est un objet) n'a pas a
contenir une reference vers la liste.


Pourquoi pas ? C'est justement parce que c'est un objet qu'il
peut s'inscrire et se désinscrire dans d'autres objets.


mais il ne DOIT PAS etre prevu pour s'inscrire et se desinscrire des
autres objets. un objet coherent n'a pas a savoir par qui il est
reference.


Ah? La conception est toujours une affaire de compromis entre
differents objectifs contradictoires, dont la simplicite et la
generalite. Si tous les objets d'une classe doivent etre reference
par un autre objet, le plus simple est de les faire s'inscrire dans
les constructeurs et desinscrire dans le destructeur.


non. si c'est le constructeur de l'objet qui inscrit l'objet dans la
liste, alors cela signifie que l'objet SAIT qu'il est dans une liste.
or, il ne doit pas le savoir.

mon objet est un thread. rien ne l'oblige a faire partie d'une liste
ou il doit s'inscrire et se desinscrire. ses methodes et ses
proprietes ne doivent donc contenir aucune information concernant une
liste quelconque.

class thread
{
thread[] liste; // faux

...
}

class thread
{
...

s_inscrire() // faux
{
...
}

se_desinscrire() // faux
{
...
}
}

etc.

C'est rare qu'il y ait des
solutions uniques a un probleme, il y a souvent plusieurs solutions
qui offrent des compromis differents.


mais il DOIT TOUJOURS y avoir une solution qui respecte les principes
de la programmation objet.

suppose que tu fasses une serie de boutons que l'on peut cliquer.
chaque bouton est un objet. si on fait une liste de ces boutons dans
le programme principal, chaque bouton ne DOIT PAS savoir qu'il est
reference par une liste.


L'analogie entre boutons et threads me semblent fortement tirees par
les cheveux.


cette analogie a seulement pour but de montrer que la liste ne doit
pas etre dans l'objet. sur ce point de vue, le bouton et le thread
sont pareils.

En fait, j'ai souvent le cas où une classe maintient un registre
statique de ses instances, accésible au moyen d'une fonction
statique. Solution qui me semble convenir parfaitement ici.


alors tes programmes ne respectent pas les principes de la
programmation objet.


Cela reste a mon avis a prouver mais en admettant cela en quoi est-ce
un probleme? La conception OO est un outil, pas une religion. Quand
un outil n'est pas celui qu'il me faut, j'en prend un autre.


dans l'enonce de mon probleme, il faut faire une conception orientee
objet. si tu prends un autre outil, alors tu ne reponds pas au
probleme.




Avatar
luc2
On Tue, 11 Jan 2005 14:34:54 +0100,
(Causse Bruno) wrote:

j'ai plusieurs threads qui tournent. chaque thread est un objet. dans
le programme principal, j'ai une liste de tous ces threads (dans un
tableau par exemple).

supposons qu'un thread se termine. comment peut-il prevenir le
programme principal, afin qu'il enleve sa reference de la liste de
threads ?

solution 1 (mauvaise) : le thread a une reference vers la liste, et il
peut la modifier. or, cela est absurde en programmation objet; le
thread (qui est un objet) n'a pas a contenir une reference vers la
liste.

solution 2 (mauvaise) : la liste est une variable globale. le thread
peut donc y avoir acces. or, une fois de plus, cela est absurde en
programmation objet; le thread n'a pas a s'occuper de mettre la liste
de threads a jour. il n'est meme pas cense savoir qu'il est repertorie
dans une liste.

existe-t-il une solution propre et non-marginale a ce probleme de
conception objet ?


ta liste est elle meme un timer (thread) qui verifie periodiquement que
sa liste de thread est a jour.


cette solution n'est pas propre. en effet, la liste ne sera pas
toujours a jour. elle ne le sera que periodiquement.


Avatar
Christophe Lephay
"luc2" a écrit dans le message de news:

On 11 Jan 2005 14:08:47 +0100, Jean-Marc Bourguet
Ah? La conception est toujours une affaire de compromis entre
differents objectifs contradictoires, dont la simplicite et la
generalite. Si tous les objets d'une classe doivent etre reference
par un autre objet, le plus simple est de les faire s'inscrire dans
les constructeurs et desinscrire dans le destructeur.


non. si c'est le constructeur de l'objet qui inscrit l'objet dans la
liste, alors cela signifie que l'objet SAIT qu'il est dans une liste.
or, il ne doit pas le savoir.


La résolution des problèmes s'accomode souvent assez mal avec les dogmes
religieux.

C'est rare qu'il y ait des
solutions uniques a un probleme, il y a souvent plusieurs solutions
qui offrent des compromis differents.


mais il DOIT TOUJOURS y avoir une solution qui respecte les principes
de la programmation objet.


Même remarque.

Cela reste a mon avis a prouver mais en admettant cela en quoi est-ce
un probleme? La conception OO est un outil, pas une religion. Quand
un outil n'est pas celui qu'il me faut, j'en prend un autre.


dans l'enonce de mon probleme, il faut faire une conception orientee
objet. si tu prends un autre outil, alors tu ne reponds pas au
probleme.


Tu dis vouloir une conception orientée objet, mais tu sembles avoir une
conception de la conception orientée objet qui t'est propre.

Tu n'arretes pas de parler de principes de la programmation objet comme des
dogmes. Peut-être serait-il temps de définir plus clairement quels seraient
ces principes ?

(c'est le sens de l'expression "celà reste à prouver" utilisée par
Jean-Marc).


Avatar
Christophe Lephay
"luc2" a écrit dans le message de news:

cette solution est equivalente a celle des listeners en java. or, ce
n'est pas quelque chose de courant en c++.


Soit une solution convient, soit elle ne convient pas. si elle convient, peu
importe qu'elle soit courante ou non. Si elle ne convient pas, peu importe
qu'elle soit courante ou non.

Qui plus est, c'est une solution courante dans les cas où elle convient
(c'est un pattern).

1 2 3 4 5