I have a question regarding thread safety and mutexes. I have two functions that may not be executed at the same time because this could cause problems:
std::mutex mutex;
void A() {
std::lock_guard<std::mutex> lock(mutex);
//do something (should't be done while function B is executing)
}
T B() {
std::lock_guard<std::mutex> lock(mutex);
//do something (should't be done while function A is executing)
return something;
}
Now the thing is, that function A and B should not be executed at the same time. That's why I use the mutex. However, it is perfectly fine if function B is called simultaneously from multiple threads. However, this is also prevented by the mutex (and I don't want this). Now, is there a way to ensure that A and B are not executed at the same time while still letting function B be executed multiple times in parallel?
If C++14 is an option, you could use a shared mutex (sometimes called "reader-writer" mutex). Basically, inside function A()
you would acquire a unique (exclusive, "writer") lock, while inside function B()
you would acquire a shared (non-exclusive, "reader") lock.
As long as a shared lock exists, the mutex cannot be acquired exclusively by other threads (but can be acquired non-exclusively); as long as an exclusive locks exist, the mutex cannot be acquired by any other thread anyhow.
The result is that you can have several threads concurrently executing function B()
, while the execution of function A()
prevents concurrent executions of both A()
and B()
by other threads:
#include <shared_mutex>
std::shared_timed_mutex mutex;
void A() {
std::unique_lock<std::shared_timed_mutex> lock(mutex);
//do something (should't be done while function B is executing)
}
T B() {
std::shared_lock<std::shared_timed_mutex> lock(mutex);
//do something (should't be done while function A is executing)
return something;
}
Notice, that some synchronization overhead will always be present even for concurrent executions of B()
, and whether this will eventually give you better performance than using plain mutexes is highly dependent on what is going on inside and outside those functions - always measure before committing to a more complicated solution.
Boost.Thread also provides an implementation of shared_mutex
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With