posts - 463, comments - 1515, trackbacks - 139

Pattern singleton che usa static? Tecnicamente sbagliato ...

Personalmente trovo che i pattern soffrano talvolta di essere usati come soluzioni generali, universali. E quando sono usati come tali si incorre in gravi errori.

Nell'implementazione singleton ad esempio, va per la maggiore la versione thread-safe. Giusto, ma che succede se faccio uso di milioni di volte di quell'oggetto? Milioni di controlli che in termini di performance fa certamente una certa differenza.
È quindi chiaro che la protezione thead-safe nell'implementare il singleton (così come altri pattern) è del tutto contestuale e non è possibile definirne una 'universale'.

Il problema non è nuovo e infatti uno degli scopi di ATL (libreria C++) era proprio di risolvere questo problema. E lo fecero in modo egregio: fornire una implementazione differente (tramite l'uso ricorsivo dei template) a seconda del contesto. Ad esempio in COM la protezione con InterlockedIncrement / InterlockedDecrement di AddRef, Release e l'uso di Critical Sections si rendono necessari solo per MTA e non in STA.
ATL provvede a una diversa generazione di codice basandosi sull'apartment in cui l'oggetto desidera vivere, ottenendo codice più snello per dimensione e performance quando i controlli non servono.

Facciamo un altro esempio, ma nel mondo managed. Tecnicamente parlando, l'uso di static per mantenere l'unica istanza è sbagliato. Dato un processo managed, esistono tante copie di dati marcate come 'static' quanti sono gli application domain in cui la classe viene utilizzata.
È quindi possibile allora trovarsi con tante istanze di singleton (contraddizione in termini) quanti sono gli application domain, cosa certamente non desiderabile nella maggior parte dei casi, o perlomeno non by-design.
Le varie soluzioni che si trovano in giro (comprese quelle che io stesso ho citato in passato nel mio blog) dovrebbero essere riviste usando un oggetto kernel come il Mutex (controllandone la ownership per essere certi di una precedente istanza).... sempre che ne valga la pena!

Questo non fa che ribadire il concetto iniziale: non esistono soluzioni universali neppure quando si parla di pattern.

Print | posted on mercoledì 26 aprile 2006 18.17 |

Feedback

Gravatar

# re: Pattern singleton che usa static? Tecnicamente sbagliato ...

vista la tua competenza sul tema xKè nn dai un check alla implementazione suggeerita nel wiki di Ugi?

Questo è il link: http://wiki.ugidotnet.org/default.aspx/UGIdotNETWiki/PatternSingleton.html

Se trovi errori lascia il tuo feedback!
26/04/2006 22.17 | Luca Minudel
Gravatar

# re: Pattern singleton che usa static? Tecnicamente sbagliato ...

Innanzitutto concordo con la tua conclusione, ma tuttavia ancora non capisco cosa intendi con "Milioni di controlli che in termini di performance fa certamente una certa differenza".

Più comodo di questo non saprei cosa potrebbe esserci - e non sto dicendo che sia la migliore in assoluto:

public static sealed class Singleton
{
public static readonly Singleton Instance = new Singleton();
}

Utilizza il membro Instance anche un milione di volte, ma quali performance hit puoi rilevare?

Detto questo, è vero che il modificatore static garantisce l'unicità solo all'interno di un appDomain, ma in quali casi è necessario accedere allo stesso oggetto da più appDomain(s)?
27/04/2006 2.57 | Simone Busoli
Gravatar

# re: Pattern singleton che usa static? Tecnicamente sbagliato ...

Ciao Luka, ci darò un occhio.
27/04/2006 9.06 | Raffaele Rialdi
Gravatar

# re: Pattern singleton che usa static? Tecnicamente sbagliato ...

Simone, l'esempio che hai riportato è thread safe e non ha performance hit ma è solo una delle implementazioni... il mio era un discorso più generale. Quando parlo di "milioni di controlli ..." intendo i check fatti tramite lock/mutex/etc..
La versione che hai riportato è molto usata ma:
- soffre del problema static in più appdomain
- la sua inizializzazione non è deterministica (vedi discorso del beforefieldinit)
- è da decidere se la gestione lazy serve o meno (a me di solito fa molto comodo decidere quando e da quale thread creare l'istanza).
Con tutto ciò è comunque un'ottima implementazione se chi la usa ne conosce i limiti.
27/04/2006 9.06 | Raffaele Rialdi
Gravatar

# re: Pattern singleton che usa static? Tecnicamente sbagliato ...

Ok, ora siamo d'accordo ;)

Ho due domande:

- in quali situazioni può succedere di avere la necessità di utilizzare lo stesso oggetto in più appDomain?

- il problema dell'inizializzazione non deterministica non può essere risolto utilizzando un costruttore static?
27/04/2006 13.17 | Simone Busoli
Gravatar

# re: Pattern singleton che usa static? Tecnicamente sbagliato ...

:)
Faccio due casi in cui l'uso di più appdomain è utile / avviene normalmente.
1) Agli ultimi community days (www.communitydays.it) ho mostrato durante la sessione della CAS quanto sia utile ed auspicabile caricare dei plugin in un appdomain differente in modo da metterli in una vera e propria sandbox che limita ciò che il plugin può fare (negargli l'accesso a disco, socket, etc. etc.).
In questo frangente l'uso di più appdomain è fondamentale perché l'appdomain costituisce il perimetro di isolamento per il codice managed all'interno di uno stesso processo.

2) Prendiamo un altro esempio: la classica applicazione asp.net. Quando aggiorni la web application, il runtime di asp.net crea un nuovo appdomain servendo le nuove richieste nel nuovo appdomain con il nuovo codice ed esaurendo le vecchie richieste dal vecchio appdomain con il vecchio codice. Questo significa che non è affatto improbabile avere nello stesso processo due appdomain con due singleton (uno per appdomain) che girino contemporaneamente.

Se ad esempio il singleton venisse usato per accedere ad una porta seriale, il risultato sarebbe disastroso.

Per la seconda domanda puoi risolvere l'indeterminatezza con il costruttore statico. Da ricordarsi sempre che il ctro statico viene chiamato al primo uso della classe e non all'avvio dell'applicazione come invece avviene nelle CRT (C Runtime Library) usate da C++, VB6, etc. etc.
27/04/2006 14.06 | Raffaele Rialdi
Gravatar

# re: Pattern singleton che usa static? Tecnicamente sbagliato ...

Un altro uso puo essere quello di un oggetto cache. utile per manetere dei dati in memoria condivisi da piu appdomain.

20/06/2006 13.24 | Giovanni D'Arienzo

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 8 and 5 and type the answer here:

Powered by: