C++11 concurrency: locks revisited

In a previous post about locks in C++11 I have shown a dummy implementation of a container class that looked like this (simplified):

One can argue that the dump() method does not alter the state of the container and should be (logically) const. However, as soon as you make it const you get the following error:

‘std::lock_guard<_Mutex>::lock_guard(_Mutex &)’ : cannot convert parameter 1 from ‘const std::recursive_mutex’ to ‘std::recursive_mutex &’

The mutex (regardless which of the four flavors available in C++11) must be acquired and released and the lock() and unlock() operations are not constant. So the argument the lock_guard takes cannot be logically const, as it would be if the method was const.

The solution to this problem is to make the mutex mutable. Mutable allows changing state from const functions. It should however be used only for hidden or “meta” state (imagine caching computed or looked-up data so a next call can complete immediately, or altering bits like a mutex that only complement the actual state of an object).

An important thing to note is that in C++11 both const and mutable imply thread-safety. I recommend this C++ and Beyond talk by Herb Sutter called You don’t know [blank] and [blank].

2 thoughts on “C++11 concurrency: locks revisited

    1. Marius Bancila Post author

      Right. For this particular example it’s enough to be a std::mutex. But as I mentioned in the post, this is a snipped from an example from an earlier post. That example contained recursive calls, and that’s why I used the recursive mutex.

      Reply

Leave a Reply