<condition_variable >
头文件主要包含了与条件变量相关的类和函数。相关的类包括 std::condition_variable
和 std::condition_variable_any
,还有枚举类型std::cv_status
。另外还包括函数 std::notify_all_at_thread_exit()
,下面分别介绍一下以上几种类型。
std::condition_variable 类介绍
std::condition_variable
是条件变量,更多有关条件变量的定义参考维基百科。Linux
下使用 Pthread
库中的 pthread_cond_*()
函数提供了与条件变量相关的功能, Windows
则参考 MSDN
。
当 std::condition_variable
对象的某个wait
函数被调用的时候,它使用 std::unique_lock
(通过 std::mutex
) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable
对象上调用了 notification
函数来唤醒当前线程。
std::condition_variable
对象通常使用 std::unique_lock<std::mutex>
来等待,如果需要使用另外的 lockable
类型,可以使用std::condition_variable_any
类,本文后面会讲到 std::condition_variable_any
的用法。
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx; // 全局互斥锁.
std::condition_variable cv; // 全局条件变量.
bool ready = false; // 全局标志位.
void do_print_id(int id)
{
std::unique_lock <std::mutex> lck(mtx);
while (!ready) // 如果标志位不为 true, 则等待...
cv.wait(lck); // 当前线程被阻塞, 当全局标志位变为 true 之后,
// 线程被唤醒, 继续往下执行打印线程编号id.
std::cout << "thread " << id << '\n';
}
void go()
{
std::unique_lock <std::mutex> lck(mtx);
ready = true; // 设置全局标志位为 true.
cv.notify_all(); // 唤醒所有线程.
}
int main()
{
std::thread threads[10];
// spawn 10 threads:
for (int i = 0; i < 10; ++i)
threads[i] = std::thread(do_print_id, i);
std::cout << "10 threads ready to race...\n";
go(); // go!
for (auto & th:threads)
th.join();
return 0;
}
结果:
10 threads ready to race...
thread 1
thread 0
thread 2
thread 3
thread 4
thread 5
thread 6
thread 7
thread 8
thread 9
好了,对条件变量有了一个基本的了解之后,我们来看看 std::condition_variable
的各个成员函数。
std::condition_variable
的拷贝构造函数被禁用,只提供了默认构造函数。