C++并发 std::condition_variable

1. std::condition_variable

C++标准库提供了条件变量的两种实现:std::condition_variablestd::condition_variable_any
它们都在标准库的头文件 <condition_variable> 内声明。

两者都需配合互斥,方能提供妥当的同步操作。

std::condition_variable仅限于与std::mutex一起使用;
由于std::condition_variable_any更加通用,它可能产生额外开销,涉及其性能、自身的体积或系统资源等,因此std::condition_variable应予优先采用,除非有必要令程序更灵活。

2. 代码

#include <mutex>
#include <condition_variable>
#include <thread>
#include <queue>
#include <iostream>


std::mutex mut;
std::queue<int> data_queue;
std::condition_variable data_cond;


void process(int data)
{
	std::cout << "process, print data: " << data << std::endl;
}


void data_preparation_thread()
{
	while (true)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(10000));

		std::lock_guard<std::mutex> lk(mut);
		
		data_queue.push(12345);
		data_cond.notify_one();

		std::this_thread::sleep_for(std::chrono::milliseconds(2000));
		std::cout << "data_preparation_thread add data to data_queue" << std::endl;
	}
}

void data_processing_thread()
{
	while (true)
	{
		std::unique_lock<std::mutex> lk(mut);

		//data_cond.wait(lk, [] {return !data_queue.empty(); });
		data_cond.wait(lk, [] {
			if (data_queue.empty())
			{
				std::cout << "data_queue is empty, wait" << std::endl;
				return false;
			}
			std::cout << "data_queue is not empty, process data" << std::endl;
			return true; 
		});

		int data = data_queue.front();
		data_queue.pop();

		lk.unlock();

		process(data);
	}
}


int main() 
{
	std::thread t1(data_preparation_thread);
	std::thread t2(data_processing_thread);

	t1.join();
	t2.join();
}



运行效果:
在这里插入图片描述
代码解析:
在这里插入图片描述
注意:

  • wait() 在内部调用传入的lambda函数,判断条件是否成立:若成立(lambda函数返回true),则wait()返回,进入下一步;否则(lambda函数返回false),wait()解锁互斥,并令线程进入阻塞状态或等待状态;
  • notify_one() 发送通知后,需要unlock后,wait() 才能收到通知;
  • data_processing_thread线程中使用的是std::unique_lock而不是std::lock_guard,原因是这样的:线程data_processing_thread在wait()等待期间,必须解锁互斥,而结束等待之后,必须重新加锁,但std::lock_guard无法提供这种灵活性;
  • 如果有多个线程在wait(), notify_one()随机唤醒一个,而 notify_all()会唤醒所有wait()的线程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值