...
The C++ Standard, [thread.mutex.class], paragraph 5 [ISO/IEC 14882-2014], states the following:
The behavior of a program is undefined if it destroys a
mutex
object owned by any thread or a thread terminates while owning amutex
object.
...
This compliant solution eliminates the race condition by extending the lifetime of the mutex:.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <mutex> #include <thread> const size_t maxThreads = 10; void do_work(size_t i, std::mutex *pm) { std::lock_guard<std::mutex> lk(*pm); // Access data protected by the lock. } std::mutex m; void start_threads() { std::thread threads[maxThreads]; for (size_t i = 0; i < maxThreads; ++i) { threads[i] = std::thread(do_work, i, &m); } } |
...
This compliant solution eliminates the race condition by joining the threads before the mutex's destructor is invoked:.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <mutex> #include <thread> const size_t maxThreads = 10; void do_work(size_t i, std::mutex *pm) { std::lock_guard<std::mutex> lk(*pm); // Access data protected by the lock. } void run_threads() { std::thread threads[maxThreads]; std::mutex m; for (size_t i = 0; i < maxThreads; ++i) { threads[i] = std::thread(do_work, i, &m); } for (size_t i = 0; i < maxThreads; ++i) { threads[i].join(); } } |
...