Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>To answer your question about why it's not threadsafe, it's not because the first call to <code>instance()</code> must call the constructor for <code>Singleton s</code>. To be threadsafe this would have to occur in a critical section, and but there's no requirement in the standard that a critical section be taken (the standard to date is completely silent on threads). Compilers often implement this using a simple check and increment of a static boolean - but not in a critical section. Something like the following pseudocode:</p> <pre><code>static Singleton&amp; instance() { static bool initialized = false; static char s[sizeof( Singleton)]; if (!initialized) { initialized = true; new( &amp;s) Singleton(); // call placement new on s to construct it } return (*(reinterpret_cast&lt;Singleton*&gt;( &amp;s))); } </code></pre> <p>So here's a simple thread-safe Singleton (for Windows). It uses a simple class wrapper for the Windows CRITICAL_SECTION object so that we can have the compiler automatically initialize the <code>CRITICAL_SECTION</code> before <code>main()</code> is called. Ideally a true RAII critical section class would be used that can deal with exceptions that might occur when the critical section is held, but that's beyond the scope of this answer.</p> <p>The fundamental operation is that when an instance of <code>Singleton</code> is requested, a lock is taken, the Singleton is created if it needs to be, then the lock is released and the Singleton reference returned.</p> <pre><code>#include &lt;windows.h&gt; class CritSection : public CRITICAL_SECTION { public: CritSection() { InitializeCriticalSection( this); } ~CritSection() { DeleteCriticalSection( this); } private: // disable copy and assignment of CritSection CritSection( CritSection const&amp;); CritSection&amp; operator=( CritSection const&amp;); }; class Singleton { public: static Singleton&amp; instance(); private: // don't allow public construct/destruct Singleton(); ~Singleton(); // disable copy &amp; assignment Singleton( Singleton const&amp;); Singleton&amp; operator=( Singleton const&amp;); static CritSection instance_lock; }; CritSection Singleton::instance_lock; // definition for Singleton's lock // it's initialized before main() is called Singleton::Singleton() { } Singleton&amp; Singleton::instance() { // check to see if we need to create the Singleton EnterCriticalSection( &amp;instance_lock); static Singleton s; LeaveCriticalSection( &amp;instance_lock); return s; } </code></pre> <p>Man - that's a lot of crap to "make a better global".</p> <p>The main drawbacks to this implemention (if I didn't let some bugs slip through) is:</p> <ul> <li>if <code>new Singleton()</code> throws, the lock won't be released. This can be fixed by using a true RAII lock object instead of the simple one I have here. This can also help make things portable if you use something like Boost to provide a platform independent wrapper for the lock.</li> <li>this guarantees thread safety when the Singleton instance is requested after <code>main()</code> is called - if you call it before then (like in a static object's initialization) things might not work because the <code>CRITICAL_SECTION</code> might not be initialized.</li> <li>a lock must be taken each time an instance is requested. As I said, this is a simple thread safe implementation. If you need a better one (or want to know why things like the double-check lock technique is flawed), see the <a href="https://stackoverflow.com/questions/1661529/is-meyers-implementation-of-singleton-pattern-thread-safe/1661564#1661564">papers linked to in Groo's answer</a>.</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload