Home arrow C++ arrow Page 2 - C++ in Theory: Why the Double Check Lock Pattern Isn`t 100% Thread Safe
C++

C++ in Theory: Why the Double Check Lock Pattern Isn`t 100% Thread Safe


Back in January, Jun Nakamura discussed Singletons in a series of three articles, and revisited the subject in May. In the May article, he described the Double Checked Locking Pattern as a way to make Singletons thread safe. Unfortunately, it's not that simple, as he explains in this article.

Author Info:
By: J. Nakamura
Rating: 4 stars4 stars4 stars4 stars4 stars / 18
August 01, 2005
TABLE OF CONTENTS:
  1. · C++ in Theory: Why the Double Check Lock Pattern Isn`t 100% Thread Safe
  2. · The Original Problem
  3. · The Double Checked Locking Pattern
  4. · Object Creation
  5. · Multiprocessor Machines
  6. · Portable Solutions

print this article
SEARCH DEVARTICLES

C++ in Theory: Why the Double Check Lock Pattern Isn`t 100% Thread Safe - The Original Problem
(Page 2 of 6 )

We have been implementing the Singleton Pattern [Gamma] in C++ to aid us in our quest to make sure we have only one unique instance of an implementation available during runtime. The Singleton is accessed exclusively through the ‘Instance()’ member function, which takes care of object creation and destruction. It also uses lazy initialization, which means that the Singleton is not created and stored until it is first accessed.

The benefit of lazy initialization is that the Singleton won’t be created until it is needed, and if it isn’t needed, memory and construction time won’t be wasted on it. It does introduce a major problem when we want to use our Singleton in a multithreaded environment.

Let us ignore policy based class design and everything else described in the previous articles, and look at the Instance function as described in "Design Patterns" [Gamma].

Singleton* Singleton::Instance () {

if (0 == pInstance)

pInstance = new Singleton;

return pInstance;

}

The Singleton should guarantee us only one instance of the implementation at runtime, but le'ts see what might happen when this code is run in a multithreaded environment.

If thread A is suspended after the if statement and before the creation of the Singleton, thread B might come in (pInstance is still 0) and create a Singleton. As soon as thread A resumes execution it creates a second Singleton. That is not what we had in mind when implementing this pattern!

Mutexes are used to synchronize thread access to sections of code. When a mutex is placed at the start of an Instance function’s body, we are sure that only one Singleton is ever created:

Singleton* Singleton::Instance() {

Guard lock(m_mutex);

if (0 == pInstance)

pInstance = new Singleton;

return pInstance;

}

However it is very time consuming to get a lock on a mutex, and this solution may introduce a performance hit when you access the Singleton a lot through the ‘Instance()’ function. It sure doesn’t make sense to have to pay this price when you need it only once (i.e. when you have to create the Singleton object). This is where the Double Checked Locking Pattern comes in.


blog comments powered by Disqus
C++ ARTICLES

- Intel Threading Building Blocks
- Threading Building Blocks with C++
- Video Memory Programming in Text Mode
- More Tricks to Gain Speed in Programming Con...
- Easy and Efficient Programming for Contests
- Preparing For Programming Contests
- Programming Contests: Why Bother?
- Polymorphism in C++
- Overview of Virtual Functions
- Inheritance in C++
- Extending the Basic Streams in C++
- Using Stringstreams in C++
- Custom Stream Manipulation in C++
- General Stream Manipulation in C++
- Serialize Your Class into Streams in C++

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials