condition_variable条件变量
一、引入头文件
#include<condition_variable>
二、wait等待
函数定义:
template<typename _Predicate>
void
wait(unique_lock<mutex>& __lock, _Predicate __p)
{
while (!__p())
wait(__lock);
}
如果__p
只是一个简单的布尔值,那么__p()
实际上就是一个变量的值。而且,无论这个变量的值如何,!__p()
都将会产生一个布尔值。这就导致了一个问题:无法在等待期间动态地检查条件,因为谓词只会在第一次调用时被评估,而之后每次调用都会得到同样的结果。
所以__p为一个可以调用的函数对象,将条件封装为一个可以调用的函数对象,以便在每次调用时都可以动态地评估条件。所以在这里使用lambda表达式返回bool值
condition_variable cv;
bool sub_run=false;
unique_lock<mutex> lock(mtx);
cv.wait(lock, [&]
{ return !sub_run; });
三、notify_all唤醒
//唤醒wait中等待的线程
cv.notify_all(); //之后wait函数会再一次执行wait函数中的lambda表达式
举例:
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
using namespace std;
int i = 0;
mutex mtx;
condition_variable cv;
bool sub_run = false;
void tf()
{
while (i < 10)
{
unique_lock<mutex> lock(mtx);
cv.wait(lock, [&]
{ return sub_run; });
cout << "子线程:" << i << endl;
i++;
this_thread::sleep_for(chrono::milliseconds(10));
sub_run = false;
cv.notify_all();
}
}
int main()
{
thread th(tf);
while (i < 10)
{
unique_lock<mutex> lock(mtx);
cv.wait(lock, [&]
{ return !sub_run; });
cout << "主线程:" << i << endl;
i++;
this_thread::sleep_for(chrono::milliseconds(10));
sub_run = true;
cv.notify_all();
}
th.join();
}
如果将cv.notify_all();注释掉
结果将会阻塞住
主线程:0
子线程:1
正常结果:
主线程:0
子线程:1
主线程:2
子线程:3
主线程:4
子线程:5
主线程:6
子线程:7
主线程:8
子线程:9
主线程:10