How does const
(pointers, references and member functions) help with thread safety in C++?

- 13,797
- 1
- 42
- 71
-
It does not. Just because a reference to a variable is const, does not imply that there are no non const references to that variable. – Chris Becke May 25 '16 at 13:07
-
@ChrisBecke Admittedly, this http://stackoverflow.com/questions/14127379/does-const-mean-thread-safe-in-c11 is a much better question, asked with more hindsight. I think the answers there show that a glib 'it does not' isn't sufficient. – James Hopkin May 31 '16 at 10:23
6 Answers
Any immutable (that is, unchangable) data is inherently thread safe - there's no risk for multiple threads concurrently reading the same read-only data because it's never going to change!
Marking a variable as const in C++ makes it read-only and thus thread safe.

- 9,898
- 7
- 40
- 59
-
-
1Initialization usually is. Why would you share an object that hasn't been fully initialized? – Greg Rogers Dec 12 '08 at 15:20
-
2also assuming all member functions are reentrant (i.e no static objects or other shared data) – Johannes Schaub - litb Dec 12 '08 at 16:46
-
I had some parallel code with a bug and I found I was doing a seemingly "innocuous" write to a member variable, which was causing a non serious memory leak. Marking methods that will be run by multiple threads `const` is a good rule to go by! – bobobobo Aug 13 '11 at 17:23
-
-1, misleading... ignores problems with ensuring seq mem consistency problems. – NoSenseEtAl Dec 28 '12 at 06:11
-
@NoSenseEAI isn't that guaranteed by the C++11 standard if you are data race free? Immutability is a way of avoiding data races. – Tim Seguine Sep 27 '13 at 18:44
-
Imagine modifying a data pointed to by an (immutable in a const method) member pointer variable -- this is perfectly valid, and totally thread-unsafe :) – mlvljr Feb 08 '14 at 00:25
-
The main problem with multiple threads is mutability. const restricts this, but since you can cast away the const-ness, it's not foolproof.

- 114,645
- 34
- 221
- 317
-
6True, but you need to do extra work to shoot yourself in the foot. – Toon Krijthe Dec 12 '08 at 09:08
-
2I agree and as a C# programmer these days I certainly miss const & – Brian Rasmussen Dec 12 '08 at 09:40
-
4No code is fool-proof, but you must protect against Murphy, not against Machiavelli. – Gorpik Dec 12 '08 at 10:37
-
You don't even need to cast it away. The only thing const implies is that YOU are not allowed to change this, NOT that no one else can. There can be many pre-existing non const references to a variable. – Chris Becke May 25 '16 at 13:10
A const member function shouldn't change state which makes it safe to call from multiple threads at the same time. However thread safety is not the purpose of const and C++ provides the mutable keyword and const_cast meaning that const does not actually guarantee thread safety and shouldn't be relied on for this purpose.

- 8,175
- 7
- 56
- 72
Const functions is not thread safe. Normaly, you can call const object methods from different threads concurrently, but if you call non const and const method from different threads you get race condition. Check this:
class Foo
{
size_t size_;
public:
...
size_t get_size() const
{
return size_
}
};
class Bar
{
boost::shared_ptr<Foo> foo_;
public:
//accessor
size_t get_size() const
{
size_t size = 0;
if (foo_)
size = foo_->size();
return size;
}
//modifiers
void init()
{
foo_ = new Foo;
}
void clear()
{
foo_ = boost::shared_ptr<Foo>();
}
};
If somebody call init method, and then call clear and get_size methods concurrently, it will cause access violation. You must use read write lock idiom. Multiple accessors can be called at the same time, and only one modifier can be called at the same time. Exemple:
class Bar
{
boost::shared_ptr<Foo> foo_;
mutable tbb::spin_rw_mutex lock_;
public:
//accessor
size_t get_size() const
{
size_t size = 0;
//lock modifiers
rw_mutex_type::scoped_lock lock(mutex, false);
if (foo_)
size = foo_->size();
return size;
}
//modifiers
void init()
{
//lock accessor and modifiers
rw_mutex_type::scoped_lock lock(mutex, true);
foo_ = new Foo;
}
void clear()
{
//lock accessor and modifiers
rw_mutex_type::scoped_lock lock(mutex, true);
foo_ = boost::shared_ptr<Foo>();
}
};
tbb::spin_rw_lock is a mutex class from threading builing blocks library

- 9,193
- 6
- 47
- 83
C++ const allows non-const aliasing such as:
Foo myVar;
const Foo* ptr1;
Foo* ptr2;
Given this, const provides no guarantees as to the immutability of your data, even if you don't do any casting or anything to get around it. If you access myVar through ptr1, you can't change it through ptr1 (assuming I got the syntax right; that was the intent.) However, it could still change through ptr2. What you really want is a separate immutable construct. This does not exist in C++.

- 67,514
- 53
- 213
- 334
Const and thread safety are orthogonal concepts.
Take a const function as an example: A class may have both const and non-const functions, and one thread may be calling a non-const function that modifies the object at the same time another thread is in its const function. In this case, marking the function const provides no safety whatsoever. Thread-safety is only achieved with locking or other synchronization primitives.

- 31
- 2