C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[HS] Design Patterns : Singleton
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Stephane Wirtel
Guest





PostPosted: Thu Jul 14, 2005 9:28 pm    Post subject: [HS] Design Patterns : Singleton Reply with quote



Bonsoir,

J'aurais aimé avoir votre avis sur la question concernant
l'implémentation du Design Pattern "Singleton" dans le cas d'une
application multi-thread.

J'ai pû constater que Mr Douglas C. Schmidt proposait comme solution, le
fait d'employer le Double Checked Locking, mais en faisant une recherche
sur google, j'ai pû constater que des exemples donnaient des résultats
contradictoires concernant ce pattern.

Auriez-vous un conseil à me fournir afin d'implémenter une classe
Singleton qui puissent fonctionner dans un environnement multi-thread ?

Merci,

Stéphane WIRTEL.
Back to top
Jean-Marc Bourguet
Guest





PostPosted: Fri Jul 15, 2005 6:16 am    Post subject: Re: [HS] Design Patterns : Singleton Reply with quote



Stephane Wirtel <stephane.wirtel (AT) belgacom (DOT) net> writes:

Quote:
Auriez-vous un conseil à me fournir afin d'implémenter une classe Singleton
qui puissent fonctionner dans un environnement multi-thread ?

L'initialiser *avant* de passer en multi-thread si tu veux eviter les
locks.

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
Laurent Deniau
Guest





PostPosted: Fri Jul 15, 2005 8:22 am    Post subject: Re: [HS] Design Patterns : Singleton Reply with quote



Stephane Wirtel wrote:
Quote:
Bonsoir,

J'aurais aimé avoir votre avis sur la question concernant
l'implémentation du Design Pattern "Singleton" dans le cas d'une
application multi-thread.

J'ai pû constater que Mr Douglas C. Schmidt proposait comme solution, le
fait d'employer le Double Checked Locking, mais en faisant une recherche
sur google, j'ai pû constater que des exemples donnaient des résultats
contradictoires concernant ce pattern.

Auriez-vous un conseil à me fournir afin d'implémenter une classe
Singleton qui puissent fonctionner dans un environnement multi-thread ?

solutions:

- creer le singleton avant d'etre en multithread
- garantir l'execution unique en multithread (voir pthread_once)
- utiliser des locks (tres lent).

Le DCL ne marche pas de facon portable.

a+, ld.

Back to top
Arnaud Debaene
Guest





PostPosted: Fri Jul 15, 2005 8:42 am    Post subject: Re: [HS] Design Patterns : Singleton Reply with quote

Stephane Wirtel wrote:
Quote:
Bonsoir,

J'aurais aimé avoir votre avis sur la question concernant
l'implémentation du Design Pattern "Singleton" dans le cas d'une
application multi-thread.

J'ai pû constater que Mr Douglas C. Schmidt proposait comme solution,
le fait d'employer le Double Checked Locking, mais en faisant une
recherche sur google, j'ai pû constater que des exemples donnaient
des résultats contradictoires concernant ce pattern.

Auriez-vous un conseil à me fournir afin d'implémenter une classe
Singleton qui puissent fonctionner dans un environnement multi-thread
Le DCLP ne marche à priori que sur des processeurs ayant une cohérence forte

de cache (X86...). Si tu veux être générique et portable, utilises un lock
pour chaque appel à "GetInstance".

Arnaud



Back to top
Stephane Wirtel
Guest





PostPosted: Fri Jul 15, 2005 11:59 am    Post subject: Re: [HS] Design Patterns : Singleton Reply with quote

Arnaud Debaene a écrit :
Quote:
Stephane Wirtel wrote:

Bonsoir,

J'aurais aimé avoir votre avis sur la question concernant
l'implémentation du Design Pattern "Singleton" dans le cas d'une
application multi-thread.

J'ai pû constater que Mr Douglas C. Schmidt proposait comme solution,
le fait d'employer le Double Checked Locking, mais en faisant une
recherche sur google, j'ai pû constater que des exemples donnaient
des résultats contradictoires concernant ce pattern.

Auriez-vous un conseil à me fournir afin d'implémenter une classe
Singleton qui puissent fonctionner dans un environnement multi-thread

Le DCLP ne marche à priori que sur des processeurs ayant une cohérence forte
de cache (X86...). Si tu veux être générique et portable, utilises un lock
pour chaque appel à "GetInstance".

Arnaud


Merci Arnaud,


Mais j'ai tout de même une question, le DCL emploit un "lock" (mutex) pour justement rendre cohérent l'accès au GetInstance ().
N'y a-t-il pas une incohérence dans le fait d'employer un lock pour chaque appel à GetInstance () ?

Pourrais-tu m'aider à mieux comprendre ?

Merci

Back to top
Jean-Marc Bourguet
Guest





PostPosted: Fri Jul 15, 2005 12:32 pm    Post subject: Re: [HS] Design Patterns : Singleton Reply with quote

Stephane Wirtel <com.descasoft (AT) wirtel (DOT) stephane> writes:

Quote:
Pourrais-tu m'aider à mieux comprendre ?

Le DCL suppose que
- l'ecriture d'un pointeur est atomique (autrement dit on va lire
ou bien l'ancienne valeur -- nulle -- ou la nouvelle, pas un
melange des deux);
- si le pointeur vers le singleton n'est pas nul, la valeur pointee
est correcte (et donc avec cet anti-idiome il n'y a pas de
synchronisation dans ce cas la). Or les methodes de coherence de
cache ne garantissent generalement rien sur l'ordre dans lequel
sont visibles sur un autre processeur des ecritures a des
adresses differentes. (Ils garantissent que tous les processeurs
partageant une adresse verront les ecritures a cette adresse dans
le meme ordre).

Seules les methodes de synchronisation fortes peuvent resoudre le
premier probleme.

Le deuxieme peut l'etre aussi en mettant dans la branche else la
barriere memoire qui va bien (voir la liste de celles de ton
processeur, si c'est l'IA64 et que tu comprends toute les nuances,
fais-moi signe, j'ai des questions a te poser Smile, c'est moins
couteuse qu'un mutex (qui comprennent une telle instruction).

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





PostPosted: Fri Jul 15, 2005 12:52 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

Laurent Deniau wrote:
Quote:
Stephane Wirtel wrote:

J'aurais aimé avoir votre avis sur la question concernant
l'implémentation du Design Pattern "Singleton" dans le cas
d'une application multi-thread.

J'ai pû constater que Mr Douglas C. Schmidt proposait comme
solution, le fait d'employer le Double Checked Locking, mais
en faisant une recherche sur google, j'ai pû constater que
des exemples donnaient des résultats contradictoires
concernant ce pattern.

Auriez-vous un conseil à me fournir afin d'implémenter une
classe Singleton qui puissent fonctionner dans un
environnement multi-thread ?

solutions:

- creer le singleton avant d'etre en multithread
- garantir l'execution unique en multithread (voir pthread_once)
- utiliser des locks (tres lent).

-- utiliser l'assembleur en ligne pour générer les
fence/barrières qu'il faut

-- il y a aussi un algorithme qui marche avec de la mémoire
locale au thread.

Reste que créer le singleton avant d'être en multithread me
semble de loin la solution préférrable. À la fois la plus
rapide et la plus portable.

J'utilise quelque chose comme :

dans le .hh :

class Singleton
{
public:
static Singleton& instance() ;

private:
static Singleton* ourInstance ;
} ;

dans le .cc :

Singleton* Singleton::ourInstance
= &Singleton::instance() ;

Singleton&
Singleton::instance()
{
if ( ourInstance == NULL ) {
ourInstance = new Singleton ;
}
return *ourInstance ;
}

(C'est un des rares cas où j'exploite l'initialisation à zéro
qui a lieu avant toute autre initialisation. Et quand je
l'utilise dans la production, il y a toujours un commentaire
explicatif au dessus la définition d'ourInstance.)

Du coup, je suis assuré que le singleton est initialisé avant
l'entrée dans main (dans la pratique, au moins, et à condition
que le .cc n'est pas dans un objet dynamique). Alors, tant que
je ne démarre pas le multithread dans le constructeur d'un objet
statique, c'est bon.

--
James Kanze GABI Software
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


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Jul 15, 2005 12:55 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

Arnaud Debaene wrote:
Quote:
Stephane Wirtel wrote:

J'aurais aimé avoir votre avis sur la question concernant
l'implémentation du Design Pattern "Singleton" dans le cas
d'une application multi-thread.

J'ai pû constater que Mr Douglas C. Schmidt proposait comme
solution, le fait d'employer le Double Checked Locking, mais
en faisant une recherche sur google, j'ai pû constater que
des exemples donnaient des résultats contradictoires
concernant ce pattern.

Auriez-vous un conseil à me fournir afin d'implémenter une
classe Singleton qui puissent fonctionner dans un
environnement multi-thread

Le DCLP ne marche à priori que sur des processeurs ayant une
cohérence forte de cache (X86...). Si tu veux être générique
et portable, utilises un lock pour chaque appel à
"GetInstance".

Le DCLP ne marche a priori pas. Un point, c'est tout. Tel qu'il
est implémenté dans ACE, il ne marche même pas sur le 80x86 le
plus primitif, avec un seul processeur. S'il donne l'air de
marcher, parfois, c'est parce que le compilateur n'optimise pas.

--
James Kanze GABI Software
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


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Jul 15, 2005 1:05 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

Jean-Marc Bourguet wrote:
Quote:
Stephane Wirtel <com.descasoft (AT) wirtel (DOT) stephane> writes:

Pourrais-tu m'aider à mieux comprendre ?

Le DCL suppose que
- l'ecriture d'un pointeur est atomique (autrement dit on
va lire ou bien l'ancienne valeur -- nulle -- ou la
nouvelle, pas un melange des deux);

Oui, mais dans la pratique, c'est rarement un problème (même
s'il y a des cas sur des Intel où ce n'est pas garanti).

Quote:
- si le pointeur vers le singleton n'est pas nul, la valeur
pointee est correcte (et donc avec cet anti-idiome il n'y
a pas de synchronisation dans ce cas la). Or les methodes
de coherence de cache ne garantissent generalement rien
sur l'ordre dans lequel sont visibles sur un autre
processeur des ecritures a des adresses differentes. (Ils
garantissent que tous les processeurs partageant une
adresse verront les ecritures a cette adresse dans le
meme ordre).

C'est pire. Le DCL suppose que toutes les écritures dans le code
apparaissent à tous les processeurs dans l'ordre qu'il serait
exécuté par la machine abstraite de la norme C++. Chose qui
n'est garantie par personne, et qui n'est en fait pas
généralement le cas dès qu'on active l'optimisation du
compilateur.

Quote:
Seules les methodes de synchronisation fortes peuvent resoudre
le premier probleme.

Le deuxieme peut l'etre aussi en mettant dans la branche else
la barriere memoire qui va bien (voir la liste de celles de
ton processeur, si c'est l'IA64 et que tu comprends toute les
nuances, fais-moi signe, j'ai des questions a te poser Smile,
c'est moins couteuse qu'un mutex (qui comprennent une telle
instruction).

En fait, il faut garantir que toutes les écritures dans la
branche qui appelle le constructeur soient visible à tous les
threads avant qu'un thread voit une valeur non-null en entrée de
la fonction. Suite à des discussions assez poussées dans
certains forums, on tend à oublier que l'implémentation de base
échoue indépendamment des problèmes de synchronisation -- dans
la mesure où il n'y a rien qui dit autrement, un compilateur est
libre de changer l'ordre des écritures dans le constructeur de
l'objet, et l'écriture du pointeur. Du coup, un autre thread
voit le pointeur non-null avant que les écritures dans le
constructeur ont eu lieu.

Les considérations sur la synchronisation ne devient critique
que quand on essaie d'adresser à ce problème sans mettre le
premier test sous le contrôle d'un lock.

--
James Kanze GABI Software
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


Back to top
Laurent Deniau
Guest





PostPosted: Fri Jul 15, 2005 2:03 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
Laurent Deniau wrote:

Stephane Wirtel wrote:


J'aurais aimé avoir votre avis sur la question concernant
l'implémentation du Design Pattern "Singleton" dans le cas
d'une application multi-thread.


J'ai pû constater que Mr Douglas C. Schmidt proposait comme
solution, le fait d'employer le Double Checked Locking, mais
en faisant une recherche sur google, j'ai pû constater que
des exemples donnaient des résultats contradictoires
concernant ce pattern.


Auriez-vous un conseil à me fournir afin d'implémenter une
classe Singleton qui puissent fonctionner dans un
environnement multi-thread ?


solutions:


- creer le singleton avant d'etre en multithread
- garantir l'execution unique en multithread (voir pthread_once)
- utiliser des locks (tres lent).


-- utiliser l'assembleur en ligne pour générer les
fence/barrières qu'il faut

-- il y a aussi un algorithme qui marche avec de la mémoire
locale au thread.

Reste que créer le singleton avant d'être en multithread me
semble de loin la solution préférrable. À la fois la plus
rapide et la plus portable.

J'utilise quelque chose comme :

dans le .hh :

class Singleton
{
public:
static Singleton& instance() ;

private:
static Singleton* ourInstance ;
} ;

dans le .cc :

Singleton* Singleton::ourInstance
= &Singleton::instance() ;

Singleton&
Singleton::instance()
{
if ( ourInstance == NULL ) {
ourInstance = new Singleton ;
}
return *ourInstance ;
}

(C'est un des rares cas où j'exploite l'initialisation à zéro
qui a lieu avant toute autre initialisation. Et quand je
l'utilise dans la production, il y a toujours un commentaire
explicatif au dessus la définition d'ourInstance.)

Du coup, je suis assuré que le singleton est initialisé avant
l'entrée dans main (dans la pratique, au moins, et à condition
que le .cc n'est pas dans un objet dynamique). Alors, tant que
je ne démarre pas le multithread dans le constructeur d'un objet
statique, c'est bon.

Si c'est ce que tu cherches, je ne vois pas l'interet du test avec NULL

class Singleton
{
public:
static Singleton& instance() ;

private:
Singleton() {}
static Singleton* myInstance ;
} ;

Singleton* Singleton::myInstance = new Singleton;
Singleton& Singleton::instance() { return *myInstance; }

Tu vois une objection avec ce code?

a+, ld.

Back to top
Jean-Marc Bourguet
Guest





PostPosted: Fri Jul 15, 2005 2:15 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:

Quote:
Si c'est ce que tu cherches, je ne vois pas l'interet du test avec NULL

La possibilite d'utiliser le singleton dans l'initialisation de
variables statiques (donc a un moment ou ourInstance n'a
potentiellement pas encore ete initialisee).

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
Laurent Deniau
Guest





PostPosted: Fri Jul 15, 2005 3:10 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

Jean-Marc Bourguet wrote:
Quote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:


Si c'est ce que tu cherches, je ne vois pas l'interet du test avec NULL


La possibilite d'utiliser le singleton dans l'initialisation de
variables statiques (donc a un moment ou ourInstance n'a
potentiellement pas encore ete initialisee).

Ok. On peut reformuler:

class Singleton
{
public:
static Singleton& instance() ;

private:
Singleton() {}
} ;

Singleton& Singleton::instance()
{
static Singleton& myInstance = *new Singleton;
return myInstance;
}

a+, ld.

Back to top
Jean-Marc Bourguet
Guest





PostPosted: Fri Jul 15, 2005 3:20 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:

Quote:
Jean-Marc Bourguet wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:

Si c'est ce que tu cherches, je ne vois pas l'interet du test avec NULL
La possibilite d'utiliser le singleton dans l'initialisation de
variables statiques (donc a un moment ou ourInstance n'a
potentiellement pas encore ete initialisee).

Ok. On peut reformuler:

class Singleton
{
public:
static Singleton& instance() ;

private:
Singleton() {}
} ;

Singleton& Singleton::instance()
{
static Singleton& myInstance = *new Singleton;
return myInstance;
}

C'est ce que j'utilise (presque, je n'aime pas l'utilisation de la
reference, j'utilise donc un pointeur) J'utilise meme

Singleton& Singleton::instance()
{
static Singleton myInstance;
return myInstance;
}

quand je n'ai pas a choisir une classe derivee. Je ne sais pas
pourquoi James fait autre chose.

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





PostPosted: Fri Jul 15, 2005 4:05 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

Jean-Marc Bourguet wrote:
Quote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:

Jean-Marc Bourguet wrote:
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:

Si c'est ce que tu cherches, je ne vois pas l'interet du test avec NULL
La possibilite d'utiliser le singleton dans
l'initialisation de variables statiques (donc a un moment
ou ourInstance n'a potentiellement pas encore ete
initialisee).

Ok. On peut reformuler:

class Singleton
{
public:
static Singleton& instance() ;

private:
Singleton() {}
} ;

Singleton& Singleton::instance()
{
static Singleton& myInstance = *new Singleton;
return myInstance;
}

C'est ce que j'utilise (presque, je n'aime pas l'utilisation
de la reference, j'utilise donc un pointeur) J'utilise meme

Singleton& Singleton::instance()
{
static Singleton myInstance;
return myInstance;
}

quand je n'ai pas a choisir une classe derivee. Je ne sais pas
pourquoi James fait autre chose.

Deux raisons. La raison pour le new est simple : je peux aussi
utiliser le singleton dans des destructeurs des statiques, sans
risque qu'il soit déjà detruit. La raison pour l'initialisation
explicite en dehors de la fonction, c'est simplement pour
assurer que instance est appelé au moins une fois pendant les
initialisations static, avant le démarrage des threads. Et que
donc, il n'a pas besoin de lock. J'aurais pu utiliser n'importe
quelle variable statique, mais je le trouve assez succinct (mais
peut-être pas trop lisible) d'utiliser précisement le pointeur
d'instance du singleton.

--
James Kanze GABI Software
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


Back to top
Laurent Deniau
Guest





PostPosted: Fri Jul 15, 2005 4:34 pm    Post subject: Re: Design Patterns : Singleton Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
Jean-Marc Bourguet wrote:

Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:


Jean-Marc Bourguet wrote:

Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> writes:


Si c'est ce que tu cherches, je ne vois pas l'interet du test avec NULL

La possibilite d'utiliser le singleton dans
l'initialisation de variables statiques (donc a un moment
ou ourInstance n'a potentiellement pas encore ete
initialisee).


Ok. On peut reformuler:


class Singleton
{
public:
static Singleton& instance() ;


private:
Singleton() {}
} ;


Singleton& Singleton::instance()
{
static Singleton& myInstance = *new Singleton;
return myInstance;
}


C'est ce que j'utilise (presque, je n'aime pas l'utilisation
de la reference, j'utilise donc un pointeur) J'utilise meme


Singleton& Singleton::instance()
{
static Singleton myInstance;
return myInstance;
}


quand je n'ai pas a choisir une classe derivee. Je ne sais pas
pourquoi James fait autre chose.


Deux raisons. La raison pour le new est simple : je peux aussi
utiliser le singleton dans des destructeurs des statiques, sans
risque qu'il soit déjà detruit. La raison pour l'initialisation
explicite en dehors de la fonction, c'est simplement pour
assurer que instance est appelé au moins une fois pendant les
initialisations static, avant le démarrage des threads. Et que
donc, il n'a pas besoin de lock. J'aurais pu utiliser n'importe
quelle variable statique, mais je le trouve assez succinct (mais
peut-être pas trop lisible) d'utiliser précisement le pointeur
d'instance du singleton.

Mais est-ce que:

class Singleton
{
public:
static Singleton& instance() ;

private:
Singleton() {}
static Singleton myInstance;
} ;

Singleton Singleton::myInstance;
Singleton& Singleton::instance() { return myInstance; }

ne rempli pas le cahier des charges?

a+, ld.

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.