C++并发 std::condition

C++并发 std::condition,第1张

文章目录
  • 1. std::condition_variable
  • 2. 代码

1. std::condition_variable

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

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

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

2. 代码
#include 
#include 
#include 
#include 
#include 


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()的线程

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1295374.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-10
下一篇2022-06-10

发表评论

登录后才能评论

评论列表(0条)

    保存