- Published on
Multithreading in const member functions
- Authors
- Name
- Gautam Sharma
- @iamgs_
Thread safety in const member functions
Let's look at a sample C++ class:
class NetworkPacket{
public:
NetworkPacket();
void* getByteOffset() const;
};
Any const member function gets a const
this
pointer as an argument. That means that we really cannot change any class state inside these type of functions. Well, sought off. C++ always has a workaround.
Enter mutable
.
mutable keyword
It is a special keyword which when used in the context of class member variables mean that their value can be mutatated inside a const
function.
Example:
class NetworkPacket{
private:
mutable size_t numBytes = 0;
public:
NetworkPacket();
void* getByteOffset() const{
numBytes += 1; // VALID: Compiler will not complain
}
};
Multithreading with const
With the introduction of mutable, multithreading becomes a little tricky now. Earlier, we were guaranteed that any queries to getByteOffset
will not change it's state since it is a const function.
Now things look quite different. Multiple threads will now mutate
the value of numBytes
and we need to be extremely careful.
We have a number of options:
- We can employ a
std::mutex
The modified class looks like:
class NetworkPacket{
private:
mutable std::mutex m;
mutable size_t numBytes = 0;
public:
NetworkPacket();
void* getByteOffset() const{
std::lock_guard<std::mutex> g(m);
numBytes += 1; // VALID: Compiler will not complain
}
};
This will work but the downside is that now NetworkPacket
can only be moved since std::mutex
does not permit copying.
- We can employ a
std::atomic
The modified class looks like:
class NetworkPacket{
private:
mutable std::atomic<unsigned> numBytes{0};
public:
NetworkPacket();
void* getByteOffset() const{
++numBytes;
}
};
This is lightweight and easier to implement than a mutex
.
Like a mutex
, a std::atomic
also makes a class move
only.
Be careful with multiple variables defined as
std::atomic
. That makes it more tricky to synchronize stuff. Astd::mutex
should be preferred in those cases.
I kept this blog nice and short. Hope you learned something out of it.
Signing out,
-G