Home arrow C++ arrow Page 4 - 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 - Object Creation
(Page 4 of 6 )

The crux of the problem lies in the way C++ objects are created. They are not always created in the same manner.

With ‘pInstance = new Singleton’, three things happen:

  1. Memory is allocated to hold a Singleton object.

  2. The Singleton is constructed inside the allocated memory.

  3. The address of the allocated memory is assigned to pInstance.

But the compiler is not constrained to perform these steps in this order! This creates a problem when step two and three are swapped:

  1. Memory is allocated to hold a Singleton object.

  2. The address of the allocated (un-initialized) memory is assigned to pInstance.

  3. The Singleton is constructed inside the allocated memory.

What will happen when thread A is suspended just after it finishes step two and thread B enters the ‘Instance()’ function?

It will detect that pInstance is not 0 anymore and may exit the function, returning the address to a section of memory that has not been initialized. Thus the code that was calling the Instance function could dereference a Singleton object that has not been constructed yet! Oops.

This problem could be solved If we could be guaranteed of the ordering of instructions, but the C and C++ standards are not strict enough in this case. The standards allow a compiler to reorder the instructions as long as the observable behavior remains the same (!). This means that the three steps leading to object construction can be reordered while maintaining the same observable behavior; one of these orders, however, is unfortunately not thread safe. Here we suffer because the C and C++ languages (and standards) have no threading notion embedded into them to help us enforce thread safety (i.e. force the compilers to generate the correct order of instructions).

Before you know it you are trying to make it clear to the compiler what your intentions are in a language that is not helping us to express ourselves correctly. Compilers are really smart these days at analyzing code, and they reorder and restructure it, trying to execute as many things at once as possible. This is great of course, but also problematic when we are trying to construct Singletons the lazy way.

Scott Meyers and Andrei Alexandrescu [Meyers/Alexandrescu] do a deep exploration into the possible solutions we could conceive of while trying to fix this problem.

Trying to force the compiler to a correct execution order of instructions by introducing variables (that will temporarily hold the address until we have finished constructing the Singleton object) will not work, because the compiler is allowed to optimize them away as long as the observable behavior remains unchanged. We can go crazy using the ‘volatile’ keyword, but in the end the problem remains, no matter how hard you try to twist the compiler’s arm.

If we want to control the order in which instructions are executed, we will have to venture outside the C and C++ language and write parts in machine dependent assembly language. Unfortunately this is not very portable and things are becoming complicated rapidly just to insure that we can construct the Singleton in a lazy way. Still this is what you will find in (platform dependent) threading libraries.


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-2014 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials