Std::condition variable
lastmod 2018-08-17created 2015-03-2410 edits
Sometimes tasks running on different threads need to wait for each other. A condition_variable lets you block a thread until a certain condition is met; the release condition can be set from another thread, or a timeout can be specified. In effect, condition_variable enables communication between threads. Think of condition_variable as the event object in the WIn32 API.
How to use
All variables involved in the wait() condition of a condition_variable must share the std::mutex passed to wait().
The common use of condition vars is something like:
// THREAD 01:
pthread_mutex_lock(&mutex);
while (!condition)
pthread_cond_wait(&cond, &mutex);
/* do something that requires holding the mutex and condition is true */
pthread_mutex_unlock(&mutex);
// THREAD 02:
pthread_mutex_lock(&mutex);
/* do something that might make condition true */
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
Example
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <string>
#include <iostream>
using namespace std;
static mutex _m;
static mutex _ms;
static condition_variable _cv;
void print(string const & str)
{
lock_guard<mutex> guard(_ms);
cout << str << endl;
}
void print(string const & str, thread::id const & id)
{
lock_guard<mutex> guard(_ms);
cout << str << id << endl;
}
void runner()
{
unique_lock<mutex> locker(_m);
print("Runner prefix wait(): ", this_thread::get_id());
_cv.wait(locker);
print("Runner suffix wait(): ", this_thread::get_id());
}
void runner2()
{
for (int i = 0; i < 3; ++i) {
print("prefix sleep.");
this_thread::sleep_for(chrono::milliseconds(1000));
print("suffix sleep.");
_cv.notify_one();
print("notify one.");
}
}
int main()
{
thread t1([&](){ runner(); });
thread t2([&](){ runner(); });
thread t3([&](){ runner2(); });
t1.join();
t2.join();
t3.join();
return 0;
}
OUTPUT: (blank lines added where nothing happens, for readability)
prefix sleep.
Runner prefix wait(): 0x700000081000
Runner prefix wait(): 0x700000104000
suffix sleep.
notify one.
prefix sleep.
Runner suffix wait(): 0x700000081000
suffix sleep.
notify one.
prefix sleep.
Runner suffix wait(): 0x700000104000
suffix sleep.
notify one.
Favorite site
- condition_variable (condition variable)
- cppreference.com: std::condition_variable
- MSDN: condition_variable class
- A Thread Pool with C++11
- condition_variable (condition variable) 1
References
-
Blog.naver_-jidon333-_condition_variable.pdf ↩