But when the implementation programming language is C++, the double checked locking strategy is often referred to as an anti-pattern - see for instance this wiki page on google code about data races.
The issue arise from the different meaning of the keyword volatile in Java vs. C++. In C++ volatile is just an hint to the compiler, meaning that we don't want any optimization performed on that variable, while in Java it implies constraints that ensures that any threads will read the most recent value of that variable.
So, that code that we see working fine for Java, is not equivalent with this (bad) rewrite in C++:
class SomethingExpensive { // ... }; volatile SomethingExpensive* se = nullptr; // !!! BAD IDEA !!! boost::mutex mxse; void setSomething() { if(se == nullptr) // !!! BAD IDEA !!! { boost::lock_guard<boost::mutex> l(mxse); if(se == nullptr) se = new SomethingExpensive(); } }The worst part of this code is that often, or even almost ever, it works. Just sometimes it gives an unexpected behavior that would be very difficult to track down to its real root.
You need atomics: http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-6-double-checked-locking.html
ReplyDeleteThank you, Joshua. The link you passed it's very interesting and add a lot of substance to the post.
DeleteJust For your Information.
ReplyDeleteWe can implement Singleton without double check locking like below ...
(From - Book - Modern C++ Design By - Andrei Alexandrescu )
class Singleton
{
public:
static Singleton* getInstance()
{
if ( !m_pSingleton )
{
Lock lock(mutex);
if ( !m_pSingleton )
m_pSingleton = new Singleton(47);
}
return m_pSingleton;
}
int getValue() { return i; }
void setValue(int x) { i = x; }
private:
static Singleton* m_pSingleton;
int i;
Singleton(int x) : i(x) { }
Singleton(const Singleton&); // Disallowed
Singleton& operator=(Singleton&); // Disallowed
~Singleton(); // Disallowed
};
Singleton3 *Singleton::m_pSingleton = NULL;
Yes, sure. And thanks for quoting Alexandrescu, a fundamental reading. The "bad idea" I was pointing in the post was about using a technique designed to work in Java when developing in C++.
ReplyDeleteYou are right, I should have completed the discussion showing a viable alternative, as the one you quoted.