1.条件变量
std::condition_variable是多线程中经常用到的一个类,它的头文件为condition_variable。它常用的成员函数包括,wait,notify_one,notify_all等。它通过wait函数进行条件判断是否阻塞,当wait阻塞后由notify_one,notify_all函数进行唤醒。
2.wait成员函数
wait的函数它有两个形参,第二个形参可选(默认为false);
实现形式为:cv_obj.wait(unique_lock对象, lambda表达式=false);没有第二个参数与lambda返回false的结果是一致的。
需要注意以下几个情形:
a.当获取到锁时,且lambda返回true时,wait不会阻塞;
b.当获取到锁时,且lambda返回false时,wait会释放锁,并一直阻塞;
c.wait处于阻塞态,直到收到notify信号为止,此后,会一直尝试获取锁,获取到锁后,重复a,b流程;
//验证:a.当获取到锁时,且lambda返回true时,wait不会阻塞;
//验证:b.当获取到锁时,且lambda返回false时,wait会释放锁,并一直阻塞;
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class Test
{
public:
Test():age_m(0)
{
cout << "Test构造函数" << endl;
}
~Test()
{
cout << "Test析构函数" << endl;
}
void set(const int age)
{
std::this_thread::sleep_for(std::chrono::seconds(1)); //等待1s,为了second线程先获取锁,以便验证获取到锁时,lambda返回flase会阻塞;
std::unique_lock<std::mutex> unilock(mutex_m);
std::this_thread::sleep_for(std::chrono::seconds(3));
cout << "set ,thread id:" << std::this_thread::get_id()<< endl;
age_m = age;
cv_m.notify_one();
}
void get()
{
std::unique_lock<std::mutex> unilock(mutex_m);
cv_m.wait(unilock, [this]{return this->age_m!=0;});
cout << "get lock, thread id:" << std::this_thread::get_id()<< endl;
cout << "age:" << age_m << endl;
}
private:
int age_m;
static std::mutex mutex_m;
static std::condition_variable cv_m;
};
std::mutex Test::mutex_m;
std::condition_variable Test::cv_m;
int main()
{
Test test;
std::thread first(&Test::set, &test, 20);
std::thread second(&Test::get, &test);
first.join();
second.join();
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
Test构造函数
set ,thread id:139901233895168
get lock, thread id:139901225502464
age:20
Test析构函数
root@epc:/home/share/test#
//验证:如果没有收到notify信号,wait会一直阻塞;
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class Test
{
public:
Test():age_m(0)
{
cout << "Test构造函数" << endl;
}
~Test()
{
cout << "Test析构函数" << endl;
}
void set(const int age)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> unilock(mutex_m);
std::this_thread::sleep_for(std::chrono::seconds(3));
cout << "set ,thread id:" << std::this_thread::get_id()<< endl;
age_m = age;
//cv_m.notify_one();
}
void get()
{
std::unique_lock<std::mutex> unilock(mutex_m);
cv_m.wait(unilock, [this]{return this->age_m!=0;});
cout << "get lock, thread id:" << std::this_thread::get_id()<< endl;
cout << "age:" << age_m << endl;
}
private:
int age_m;
static std::mutex mutex_m;
static std::condition_variable cv_m;
};
std::mutex Test::mutex_m;
std::condition_variable Test::cv_m;
int main()
{
Test test;
std::thread first(&Test::set, &test, 20);
std::thread second(&Test::get, &test);
first.join();
second.join();
return 0;
}
//打印结果(一直处于阻塞状态)
root@epc:/home/share/test# ./test
Test构造函数
set ,thread id:139977009768192
^C
root@epc:/home/share/test# ^C