Singleton

Creating a singleton object :

class Singleton
{
public:
static Singleton* Instance( );
~Singleton( );
private:
Singleton( );

//make sure copy constructor and assignment operator are inaccessible otherwise you may accidentally get copies of
// singleton object

Singleton(Singleton const&); // Don’t Implement
void operator=(Singleton const&); // Don’t implement
};


static Singleton* object;=NULL: // Guaranteed to be destroyed.

// Instantiated on first use.

Singleton* Singleton::Instance() {
              /* if object is not initialized, acquire lock */
              if (object == 0) {
                      lock.AcquireLock();
                    /* If two threads simultaneously check and pass the first “if”
                   * condition, then only the one who acquired the lock first
                    * should create the instance */
              if (object == 0) {  //Double Checked locking
                     object = new T;
                }
                lock.ReleaseLock();
         }
   return object;

}

Avoid Singleton Object being Destroyed by other thread :

class Singleton; // forward declaration
Singleton * s = NULL; // global object available to all threads

// Place this class in a location unavailable to all threads except Main thread
class ManageSingleton
{
public:

static void DestroySingleton(Singleton * s)

        {

    delete s;
}

}

class Singleton
{
friend class ManageSingleton;
protected:
~Singleton() {}
};

void main()
{
s = new Singleton;
while (…)
{
// other threads access Singleton object until program is finished
}

// Program is now finished; destroy Singleton object
ManageSingleton::DestroySingleton(s);
}

When does double lock checking fails?

it can fail in case of compiler optimizations.
A* a = new A(“str”);

// Above statement can be split into three parts.
(a) allocate Memory
(b) Call constructor
(c) Assign value to ‘a’

// But The compiler can optimize in following manner:(case 2)
(a) allocate Memory
(c) Assign value to ‘a’
(b) Call constructor.
// This is because the whole thing is between two sequence points.

// Simple Double checked lock. (I know there are many other problems with this).
if (a == null) // (Point B)
{
Lock lock(mutex);
if (a == null)
{
a
= new A(“str”); // (Point A).
}
}
a
->doStuff();

// Think about the situation.
// Thread 1: Reaches point A. Executes (a)(c) in case 2
// Thread 1: Is about to do (b) and gets unscheduled.
// Thread 2: Reaches point B. It can now skip the if block
// Remember (c) has been done thus ‘a’ is not NULL.
// But the memory has not been initialized.
// Thread 2 now executes doStuff() on an uninitialized variable.

// The solution to this problem is to move the assignment of ‘a’ in following manner:
// To the other side of the sequence point.
if (a == null) // (Point B)
{
Lock lock(mutex);
if (a == null)
{
A
* tmp = new A(“str”); // (Point A).
a
= tmp;
}
}
a
->doStuff();

When should a singleton object be created ?

A singleton should be used if and only if, we need both the traits it offers: If we need global access (which is rare, because globals are generally discouraged) and we need to prevent anyone from ever creating more than one instance of a class (which sounds  like a design issue. The only reason of creating two instances would corrupt our application state – probably because the class contains a number of static members. In which case the obvious answer is to fix that class. It shouldn’t depend on being the only instance.

Resolving technical problems:

Solve your technical problems instantly

We provide Remote Technical Support from Monday to Sunday, 7:00PM to 1:00 AM

Mail your problem details at writeulearn@gmail.com along with your mobile numberand we will give you a call for further details. We usually attend your problems within 60 minutes and solve it in maximum 2 days.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.