C++多线程6-条件变量

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
发布了32 篇原创文章 · 获赞 3 · 访问量 1409

猜你喜欢

转载自blog.csdn.net/m0_37582216/article/details/102595759