PATRON SINGLETON (AVEC PROTECTION CONTRE LES MULTI THREAD), TUTORIAL PATRON 1

Lucyberad Messages postés 414 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 26 juillet 2007 - 12 juin 2005 à 23:50
cs_dragon Messages postés 2336 Date d'inscription samedi 14 juillet 2001 Statut Membre Dernière intervention 5 mai 2009 - 24 juil. 2005 à 19:12
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/31960-patron-singleton-avec-protection-contre-les-multi-thread-tutorial-patron-1

cs_dragon Messages postés 2336 Date d'inscription samedi 14 juillet 2001 Statut Membre Dernière intervention 5 mai 2009 6
24 juil. 2005 à 19:12
oui, il doit y avoir un problème dans ton singleton.
en passant, mieux vaut toujours mettre tes composant private et faire un getTexte à la place

ceci serait suffusant
console.writeline(form2.getInstance().getTexte())
Lucyberad Messages postés 414 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 26 juillet 2007 3
24 juil. 2005 à 17:33
dsl pour le double post mais c'est vbfrance qui as merdouillé...
sinon ben j'ai fait plein de test comme t'as dit mais le prblm est plus compliqué que ca:
la form1 initialise la form2.
la form2 contient une textbox
la form2 contient un bouton qui lance un sub sur un module
et la fonction de ce module recupère l'info du textbox de la form2.

j'ai mis ce code dans le module:
dim formulaire2 as form2 = form2.getinstance
dim string1 as new string
string1 = formulaire2.textbox1.text
console.writeline(string1)

et ben string1 est nul, par contre, quand je mets:
dim string1 as new string
string1 = WindowsApplication1.Form2.textbox1.text
console.writeline(string1)

ca marche...
donc en fait le singleton, malgré qu'il contienne la valeur windowsapplication1.form2, n'est pas égal a windowsapplication1.form2
quand je remplace formulaire2 par windowsapplication1.form2, ca fonctionne MAIS attention! windowsapplication1.form2 ne fonctionne QUE si la fonction ne se trouve dans le meme thread que la form2.

donc voila, contrairement a ce que pourrait laisser croire visual: formulaire2 n'as pas de valeur ! (fodrait que ce soit une fonction pour que on puisse envisager de lui donner une valeur)
le singleton permet donc d'initialiser une form avec une protection multithread. Elle n'arrive pas a en recuperer l'instance dans mon cas.
quand on utilise windowsapplication1.form2, ca mets cette erreur: "Object reference not set to an instance of an object."

voila j'espere que c'est plus clair...
cs_dragon Messages postés 2336 Date d'inscription samedi 14 juillet 2001 Statut Membre Dernière intervention 5 mai 2009 6
24 juil. 2005 à 00:33
c'est dur de te répondre sans voir exactement le code
un petit truc quand tu es pas sur si ce que retourne le singleton est bien correct. Met toi une variable globale qui est vide en partant et dans ton new met lui une valeur.

démare ton code est fait lui un break quand tu le rappelles. Si ta varialbe globale de test est bien initialisé, il te retourne bien l'instance correctement, donc le problème viens d'ailleur. Si ta variable est vide, bien ton instance est mal créé, donc le problème viens du singleton qui doit avoir une erreur
Lucyberad Messages postés 414 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 26 juillet 2007 3
23 juil. 2005 à 23:28
alors en effet je me suis reinteressé plus pronfodemment (apres avoir appris bocoup sur le multithread) et finalement j'ai compris ce script plutot difficile du premier abord mais en fait plutot simple quand on le comprend. Voila, je me suis interessé de plus pres qu'avant (avec mes connaissance toute fraiche) et en fait je me rend compte que c'est abordable pour un esprit comme moi ^^, voila en fait c'est juste un script qui permet de bloquer l'evenement NEW lors d'un initialisation de form si celle si existe deja et synclock permet d'eviter que 2 multitthread fasse ensemble merder le script (utilise pour les thread mis dans des boulce appelant l'ouverture d'une form). Voila, mon probleme principal venait du fait que je croyais que .getinstance était integré au framework, finalement j'ai voulu l'utiliser hors de ta source et j'ai compris qu'en fais ce code était dans le code concepteur de la form (etant desormais dans un fichier a part dans visual 2005 ce qui est plutot chiant). Donc voila je sais comment eviter que des form s'initialise 2 fois et ceci a partir d'un thread mais j'aimerais savoir comment je peut faire pour obtenir le controle des objet sur cette meme form: je m'explique, j'ai fait un code comme ceci qui se trouve dans un thread:

dim formulaire2 as form2 = form2.getinstance
dim string1 as new string
string1 = formulaire2.label1.textbox1
console.writeline(string1)

malheuresement, il s'avere que string1 ne renvoie aucune donnée, il est vide (alors que je rempli bien le bon textbox ^^)
en clair, j'obtient: string1 = ""
donc voila, j'ai beau remplasser:
formulaire2.label1.textbox1 par form2.label1.textbox1
mais form2 n'est plus reconnu...

voila si on pouvais m'aider svp, ca m'aiderait super bien.
d'ailleur je supsonne bien que le prblm vien du fait que form2.getinstance donne pas une "redirection" vers la form2. puisque finalement, son but principal ne sert juste a initialiser ^^

@+
Lucyberad
jmenfous Messages postés 117 Date d'inscription mardi 21 janvier 2003 Statut Membre Dernière intervention 2 juillet 2009 1
12 juil. 2005 à 15:57
ba... disons que mes tests sont un peu... fausses alors

J'ai fais mes tests sur Bi-Xeon 2Ghz sous 2003 Standard Edition avec 2Go de RAM (donc windows voit 4 processeurs). Ma seconde machine a des processeurs a 2,4Ghz... on ne voit pas trop la differance... ou alors ca passe trop vite pour moi (vive les joies de l'administration reseau quand on developpe aussi ;-))

De toute maniere j'envisage plutot une limitation dynamique en fonction de la charge de la machine (% de charge des processeur sur une certaine dirree limite par exemple), pour un poste client c'est plus viable.

PS: petite remarque, on observe une legere difference de performances des applis DOT NET sous 2003, mais ce n'est pas enorme contrairement a ce que dit Microsoft.
cs_dragon Messages postés 2336 Date d'inscription samedi 14 juillet 2001 Statut Membre Dernière intervention 5 mai 2009 6
12 juil. 2005 à 15:04
windowsxp a une limite de 20 threads je crois. Sinon il ne fait plus du vrai threading ou sinon faut avoir un biprocesseur pour aller au delà.
jmenfous Messages postés 117 Date d'inscription mardi 21 janvier 2003 Statut Membre Dernière intervention 2 juillet 2009 1
12 juil. 2005 à 10:01
Ok merci pour l'info.

Je vai voir ce que nous reserve le framework 2 a ce sujet... enfin plus particulierement sur la limitation des threads. Histoire de faire des programmes dont on limiterait le nombre de threads afin de ne pas creer un programme du type "a genou les pcs, me voila"... enfin j'appel ca comme ca.
cs_dragon Messages postés 2336 Date d'inscription samedi 14 juillet 2001 Statut Membre Dernière intervention 5 mai 2009 6
12 juil. 2005 à 00:46
oui la performance y sera
Voici l'astuce
If IsNothing(instance) Then
SyncLock GetType(tb_users)
If IsNothing(instance) Then

Donc si le singleton est créé, il va jamais faire le SyncLock, donc le singleton reste rapide. Et si 2 thread arrive en même temps lors de la création, 1 des threads va faire le SyncLock, mais quand le 2e thread sera débloquer, il va tombé sur la 2e vérification d'instance. Donc il va pas recréé le singleton.

Donc l'astuce est ici. si on a aucun thread. On peut écrire seulement ceci

If IsNothing(instance) Then

ça sera suffisant, puisque 2 thread peut pas arrivé en même temps, vu que l'application arrive jamais avec des threads.
jmenfous Messages postés 117 Date d'inscription mardi 21 janvier 2003 Statut Membre Dernière intervention 2 juillet 2009 1
11 juil. 2005 à 19:15
Comme toujours j'aime bien ta source, qui dans le cas présent ne doit pas parler à tout le monde malheureusement.

Mais avec ce bon vieu copain MUTEX vous avez regardé ce que ça donne (en therme de performance)? Car le mutex va bloquer les autres threads mais est-ce que la reprise va être rapide?
cs_dragon Messages postés 2336 Date d'inscription samedi 14 juillet 2001 Statut Membre Dernière intervention 5 mai 2009 6
13 juin 2005 à 09:41
non pas dutout
par contre tu peux faire ce que tu dit avec le synlock. Quand un thread entre dans le synlock, ça bloque tout les autres thread qui veulent avoir accès au même objet, puis libère le thread suivant en quittant le synlock. Et ainsi de suite.

sauf ça implique que tes thread vont arrêter un après l'autre, donc ralentir ton code. La protection du singleton est que oui ça va ralentir lor de la création, maisune fois créé, les threads ne seront pus jamais ralenti par le synlock. Donc rapide une fois l'instance créé
Lucyberad Messages postés 414 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 26 juillet 2007 3
13 juin 2005 à 08:29
saluit, ca va j'ai maintenant compris le principe d'un singleton :)
en fait je me demandait si ca revenait pas au meme qu'un pool de threads, file d'attente qu execute les thread 1 par 1, on y rajoute le thread a la file d'attente, et ca lance 1 par 1 les thread,
plus d'info sur le site de windaube:
http://www.microsoft.com/france/msdn/technologies/outils/vbasic/info/info.asp?mar=/france/msdn/technologies/outils/vbasic/info/vbtchasyncprocvb.html#vbtchasyncprocvbanchor8

voila,voila...
encore merci pour cette source d'une grande qualité!
@+
L U C Y I3 E R @ D
cs_dragon Messages postés 2336 Date d'inscription samedi 14 juillet 2001 Statut Membre Dernière intervention 5 mai 2009 6
13 juin 2005 à 03:18
oui, il y a 2 exemples distinst. Mais les 2 exemples sont des singleton. Un normal avec une classe qui me sert de base de donnée en RAM et le zip qui est un singleton appliqué a une forme.

Je trouvais qu'on pouvait mieux comprendre avec 2 exemples distincts, surtout que le zip a une astuce qui fait un singleton unique tant que la form est ouverte. Dès ça fermeture, le singleton se ferme.

peut-être pratique dans certaine occasion pour pas reloader en mémoire des form complexe. On cré l'instance (la form) puis après on fait un Update (patron MVC, le prochain tutorial sur les patrons que je vais faire) qui configure l'interface. Comme ça, l'interface est créé une fois, mais rafraichie a chaque intance.

un module est un genre de patron, mais automatique. Je déteste ce qui est automatique, on fini toujours par être trop limité lol.

pour expliquer le isnothing et le synlock, faut suivre ceci
si 2 threads arrive en même temps
1: premier thread
2: 2e thread

si l'instance est déjà créé, les 2 treads lit le singleton en même temps (faut faire attention de bien mettre les variable locales, sinon les 2 threads vont changer les valeurs en même temps et gros risque d'erreurs)

si l'instance est pas créé et les 2 thread arrive en même temps, voici ce qui se passe

1: le thread détecte que l'instance (singleton) est pas créé (isnothing )
2: détecte la même chose
1: bloque les threads
2: le thread est bloquer par 1
1: le thread vérifique que l'instance est toujours pas créé (non)
1: il créé l'instance
1: il débloque les threads
2: le threads est débloqué
1: il retourne l'instance (return)
2: 2e détection si le thread existe (oui, il viens d'être créé)
2: retourne l'instance

Voici exactement ce qui se produit si 2 threads arrivent en même temps. c'est impossible de plus optimiser que ça, puisque si l'instance est créé, les 2 thread se bloqueront jamais et aucun ralentissement se fera sentir

c'est ça un patron. Un algo parfait pour une situation fréquente.

l'idéal est de créé les singleton en partant, en loadant l'application par exemple. Mais le singleton est aussi prévu de se loader en mémoire a n'importe quel moment.
Lucyberad Messages postés 414 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 26 juillet 2007 3
12 juin 2005 à 23:59
par contre je vien de regarder le code, et puis la aussi une chose me surprend, il est ou le code que tua fiche et sur lequel j'ai fait des recherche?
sinon, on y voit bien une option que je cherchais depuis des lustre, palier au new qui fesait chier pour declarer les form (j'ai fais a chaque fois ca avec un modules ou je declarai les forms toute a new et je fesait des fonction qui les utilisait)
voila.
plusieur choses sont trouble dans cete source mais le tout est extrement bien expliqué malgré le taux de complexité de la choses.
encore merci !
Lucyberad Messages postés 414 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 26 juillet 2007 3
12 juin 2005 à 23:50
salut,
si je comprend bien un singleton rassemble tout les threads present de l'application, pourquoi pas un seul thread alors?
par contre j'ai analysé ta source:
si je comprend bien, c une operation qui permet de bloquer un thread afin qu'un autre puisse se servir de ses données avant qu'il se ferme pour et que ses données ne soit plus utilisable?
en clair nous avons: un isnothing qui verfie que celui est actif (qu'il ne se soit aps terminer avant qu'on commence), un synlock qui lock (bloque) le thread, et on en lance un autre qui utilisera les données du thread locké (j'ai vu apr contre que c'est tb_user qu'on bloque et on lance tb_user, je comprend pas trop la)
sinon le thread tb_user lance getuser qui lui lance new, je pense que c'est ca...

voila ce que j'ai pu en deduire et je te l'affiche car je sais pas trop si c'est comme ca qu'il fo le comprendre.
il se peut que j'ai faux sur toute la ligne auquel cas j'aimerais bien que tu me le dise ^^

@+
L U C Y I3 E R @ D

ps: je te remercie de poster des source de si rare et bien commenté (du moins SI on les comprend mal, il y en as ce qui fait une choses très positive, 10/10 sans hesiter)...
Rejoignez-nous