C++
  Home arrow C++ arrow Page 4 - C++ in Theory: Why the Double Check Lock P...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Dedicated Servers  
Actuate Whitepapers 
Moblin 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C++

C++ in Theory: Why the Double Check Lock Pattern Isn`t 100% Thread Safe
By: J. Nakamura
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 12
    2005-08-01

    Table of Contents:
  • C++ in Theory: Why the Double Check Lock Pattern Isn`t 100% Thread Safe
  • The Original Problem
  • The Double Checked Locking Pattern
  • Object Creation
  • Multiprocessor Machines
  • Portable Solutions

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT

    Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here

    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.

    More C++ Articles
    More By J. Nakamura


       · well, why not add an intermediate step to make sure that pInstance is only != 0 when...
       · What about this:if(!initialized){ lock(); if(instance == 0){ instance =...
       · your didn't read the article carefully.p3:Trying to force the compiler to a...
       · if the first thread set the initialized = true first, the second thread will assume...
     

    C++ ARTICLES

    - Large Numbers
    - Dijkstra`s Shunting Algorithm with STL and C...
    - Brief Introduction to the STL Containers
    - The Standard Template Library
    - Templates in C++
    - C++ Programmer Alerts
    - C++ Programming Tips
    - First Steps in (C) Programming, conclusion
    - First Steps in (C) Programming, continued
    - First Steps in (C) Programming, introduction
    - C++ Preprocessor: Always Assert Your Code Is...
    - C++ Preprocessor: The Code in the Middle
    - Programming in C
    - Temporary Variables: Runtime rvalue Detection
    - Temporary Variables: Chasing Temporaries Away







    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway