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.