

C++ and the Perils of Double-Checked Locking (2004) [pdf] - lelf
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf

======
StephanTLavavej
This has been fixed in C++11. In fact, there are several alternatives.
<atomic> provides sequential consistency by default, preventing the seemingly-
bizarre operation reorderings described here. std::call_once() does exactly
what it says: it allows multiple threads to call something exactly once (with
robust behavior in the face of exceptions). And the magic statics feature in
the Core Language makes the construction and destruction of function-local
statics thread-safe (protecting actual usage is up to you).

~~~
gilgoomesh
Yes, the DCLP can be done safely if you use atomic operations for the
comparisons to 0.

Sadly though, atomic operations are still quite expensive, depending on CPU,
taking as much as 40-50 times as long as a basic comparison. But you gotta do
what you gotta do.

~~~
StephanTLavavej
You need an atomic load, followed by an ordinary comparison. On x86 and x64,
this is cheap (properly-aligned loads and stores are already atomic, and the
architectures do very little reordering that has to be prevented). On ARM it's
more expensive.

You're probably thinking of things like atomic increments, which are one to
two orders of magnitude more expensive than an ordinary increment.

------
Animats
While there are now some atomic operations in C++, it's not like the language
gives you any help with concurrency. The language has no idea what's shared
and what isn't. Only a few languages (Ada and Erlang come to mind) know at
compile time what's shared and what isn't. In a world where everything bigger
than a watch now has multiple CPUs sharing memory, this is kind of
embarrassing.

------
nl
The Wikipedia page on double checked locking[1] is pretty good. It's got a
good discussion of this C++ problem (and how C++11 fixes it) as well as the
problems in Java (prior to JDK 5).

[1] [http://en.wikipedia.org/wiki/Double-
checked_locking](http://en.wikipedia.org/wiki/Double-checked_locking)

