Reputation: 2920
Is std::mutex as a member variable thread-safe for multiple threads?
There is an instance of a class has a variable and mutex as a member.
Each function is called in different threads.
I am curious that is it okay to use a mutex like this?
There are lots of example codes using a kind of wrapper class for mutex like guard or something.
I prefer to use it simply and want to unlock explicitly. Not in destructing time.
#include <mutex>
#include <stdio.h>
class A {
private:
bool _is;
std::mutex _mutex;
}
// this function runs in Thread A
void A::read() {
_mutex.lock();
printf("%d", _is);
_mutex.unlock();
}
// this function runs in Thread B
void A::write() {
_mutex.lock();
printf("%d", _is);
_is = !_is;
_mutex.unlock();
}
Upvotes: 4
Views: 3340
Reputation: 73061
It will basically work, but there are a couple of "gotchas" you'll want to watch out for:
If the code in between the lock()
and unlock()
calls ever throws an exception (or uses the return
or goto
keywords), the unlock()
call might never be reached, and thus your mutex will remain locked indefinitely. This will probably result in the deadlocking of your application, as every subsequent thread that tries to the lock the mutex will end up waiting forever for their own lock()
call to return. (This hazard goes away if you use a lock_guard/RAII approach instead, which is why that is the recommended/safer way to do it)
If the A
object gets deleted while it is still accessible to other threads, it will likely result in undefined behavior, since the member-variable-mutex the threads depend on for serialization will have been destroyed. (The typical way to avoid this is to make sure all threads have been join()
'd before the mutexes they depend on are destructed -- or by moving the mutexes out of the object and into some higher-level object that you can guarantee won't get destroyed while the threads are still running)
Upvotes: 11