std::condition_variable
是 C++11 多线程编程中的条件变量。
一般用法: 线程 A 等待某个条件并挂起,直到线程 B 设置了这个条件,并通知条件变量,然后线程 A 被唤醒。
构造
仅支持默认构造函数,拷贝、赋值和移动(move)均是被禁用的。
1
| std::condition_variable cv;
|
等待
无条件等待
阻塞当前线程直到被其他线程通知唤醒。
1
| void wait (unique_lock<mutex>& lck);
|
有条件等待
只有当 pred
条件为 false
时才会阻塞当前线程,并且在收到其他线程的通知后只有当 pred
为 true
时才会被解除阻塞。
1 2
| template <class Predicate> void wait (unique_lock<mutex>& lck, Predicate pred);
|
相当于
1 2 3 4
| while (!pred()) { wait() }
|
通知
通知线程可以使用 notify_one()
通知一个线程,或一次使用 notify_all()
通知所有线程。
简单例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <atomic> #include <condition_variable> #include <mutex> #include <thread> #include <chrono> #include <iostream>
std::mutex mtx; std::condition_variable cv; std::atomic<bool> ready;
void wait(int id) { std::cout << "thread: " << std::this_thread::get_id() << " id: " << id << " start.\n";
std::unique_lock<std::mutex> lck(mtx); cv.wait(lck, [] { return ready.load(); });
std::cout << "thread: " << std::this_thread::get_id() << " id: " << id << " done.\n"; }
void set_ready() { std::cout << "set_ready(): " << std::endl; ready.store(true); cv.notify_one(); }
int main(int argc, char **argv) { ready.store(false);
auto t_1 = std::thread(wait, 1); auto t_2 = std::thread(wait, 2);
std::this_thread::sleep_for(std::chrono::seconds(1)); set_ready();
std::this_thread::sleep_for(std::chrono::seconds(1)); set_ready();
std::cout << "join...." << std::endl; t_1.join(); t_2.join(); std::cout << "all done" << std::endl;
return 0; }
|
输出:
1 2 3 4 5 6 7 8
| thread: 139827702187776 id: 1 start. thread: 139827693795072 id: 2 start. set_ready(): 1 thread: 139827702187776 id: 1 done. set_ready(): 1 join.... thread: 139827693795072 id: 2 done. all done
|