Reputation: 4004
There is a set of problems in which mutexes themselves (without additional stuff like condition variables) can be used to synchronize threads.
For example, let's say I want a background thread to perform some possibly-time-consuming initialization and then to perform its main job, but the main job should start not earlier than I give a signal from the main thread:
std::thread backgroundThread ([]() {
initialize ();
waitForSignalQ ();
doMainJob ();
});
…;
emitSignalQ ();
Yes, I know that I can use mutex + boolean variable + condition variable to implement waitForSignalQ
and emitSignalQ
. Or, I can use void-returning future + void-returning promice for the same purpose, as Scott Meyers suggests.
But the simpler approach here seems to be using just a single mutex:
std::mutex myMutex;
std::unique_lock <std::mutex> backgroundThreadCantStartItsMainJob (myMutex);
std::thread backgroundThread ([&myMutex]() {
initialize ();
// This line won't return until myMutex is unlocked:
std::lock_quard <std::mutex> (myMutex);
doMainJob ();
});
…;
// This line will unlock myMutex:
backgroundThreadCantStartItsMainJob.unlock();
But is this approach valid? Or are there some drawbacks (for example: OS-level mutex-locking time limit, false positives from software analysis tools, etc)?
P. S.:
• Yes, I know that the problems will arise if myMutex
isn't unlocked (due to an exception before backgroundThreadCantStartItsMainJob.unlock()
or etc), but the question is not about that (with condvar and future approaches we get the same problem if the main thread "forgets" to emit the signal Q).
• Yes, I know that in practice it might make sense to have several variants of signal Q (like "proceed to the main job" vs. "cancel"), the question is not about that (as well as the condvar and future approaches, the discussed approach allows passing extra data too).
Upvotes: 1
Views: 856
Reputation: 11400
There's no specific downsides to locking a mutex for a long time.
If I understood correctly, you have a thread that will lock a mutex during its init. Another thread will try to get that mutex (to be sure the init of the other thread is finished) and then get the mutex for the rest of the program runtime.
That is fine. There's no runtime cost with having the mutex. The OS will not time it out or anything. The challenge is a software engineering one: Make it clear, readable and understandable for the person that will have to maintain it. Apart from that, the architecture is really up to you.
Upvotes: 2