While implementing a thread pool pattern in C++ based on this, I came across a few questions.
Let's assume minimal code sample:
std::mutex thread_mutex;
std::condition_variable thread_condition;
void thread_func() {
std::unique_lock<std::mutex> lock(thread_mutex);
thread_condition.wait(lock);
lock.unlock();
}
std::thread t1 = std::thread(thread_func);
- Regarding cppreference.com about
conditon_variable::wait()
,wait()
causes the current thread to block. What is locking the mutex then for when I only need one thread at all usingwait()
to get notified when something is to do? unique_lock
will block the thread when the mutex already has been locked by another thread. But this wouldn't be neccesary as long aswait()
blocks anyway or what do I miss here?
Adding a few lines at the bottom...
std::thread t2 = std::thread(thread_func);
thread_condition.notify_all()
- When
unique_lock
is blocking the thread, how willnotify_all()
reach both threads when one of them is locked byunique_lock
and the other is blocked bywait()
? I understand that blockingwait()
will be freed bynotify_all()
which afterwards leads to unlocking the mutex and that this gives chance to the other thread for locking first the mutex and blocking thread bywait()
afterwards. But how is this thread notified than?
Expanding this question by adding a loop in thread_func()
...
std::mutex thread_mutex;
std::condition_variable thread_condition;
void thread_func() {
while(true) {
std::unique_lock<std::mutex> lock(thread_mutex);
thread_condition.wait(lock);
lock.unlock();
}
}
std::thread t1 = std::thread(thread_func);
std::thread t2 = std::thread(thread_func);
thread_condition.notify_all()
- While reading documentation, I would now expect both threads running endlessly. But they do not return from
wait()
lock. Why do I have to use a predicate for expected behaviour like this:
bool wakeup = false;
//[...]
thread_condition.wait(lock, [] { return wakeup; });
//[...]
wakeup = !wakeup;
thread_condition.notify_all();
Thanks in advance.