C++ std::condition_variable 条件变量

std::condition_variable 是 C++11 标准引入的,用于实现线程间的同步,用于线程实现带有条件的去竞争锁的问题。

当我们使用互斥锁时,多个线程只要发现锁空闲,就会去抢锁,争夺执行权限。如果抢到锁的线程没有满足某个条件,它就不具备执行权限,浪费系统资源。所以,我们希望线程在满足某个条件时,再去抢锁。

条件变量能够为互斥锁构建一个条件,当线程去争抢该锁时,必须满足相应的条件。如果不满足条件,则进入阻塞等待。当条件满足时,再被唤醒。

1. 问题场景

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<thread>
#include<queue>
#include<mutex>
#include<chrono>


const size_t buffer_size = 5;
std::queue<size_t> buffer;
std::mutex buffer_mutex;


void do_produce()
{
	size_t index = 0;
	while (true)
	{
		buffer_mutex.lock();
		if (buffer.size() < buffer_size)
		{
			std::cout << buffer.size() << " " << std::this_thread::get_id() << " 生产:" << index << std::endl;
			buffer.push(index++);
		}
		buffer_mutex.unlock();
		std::this_thread::sleep_for(std::chrono::milliseconds(300));
	}
}

void do_consume()
{
	while (true)
	{
		buffer_mutex.lock();
		if (buffer.size() > 0)
		{
			size_t element = buffer.front();
			std::cout << std::this_thread::get_id() << " 消费:" << element << std::endl;
			buffer.pop();
		}
		buffer_mutex.unlock();
		std::this_thread::sleep_for(std::chrono::milliseconds(500));
	}
}

// 不足
// 生产者和消费者都在每次操作前都尝试获取锁,这可能会导致频繁的上下文切换和锁竞争,降低程序的性能,特别是在多线程环境下

void test()
{
	std::thread producer(do_produce);
	std::thread consumer1(do_consume);
	std::thread consumer2(do_consume);

	producer.join();
	consumer1.join();
	consumer2.join();
}


int main()
{
	test();
	return EXIT_SUCCESS;
}
#endif

2. 问题解决

#if 0
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<thread>
#include<queue>
#include<mutex>
#include<chrono>


// 条件变量
std::condition_variable producer_condition;
std::condition_variable consumer_condition;

std::queue<int> buffer;
std::mutex buffer_mutex;


void do_produce()
{
	int index = 0;
	while (true)
	{
		{
			std::unique_lock<std::mutex> lock(buffer_mutex);
			producer_condition.wait(lock, [&]() {return buffer.size() < 5; });
			std::cout << std::this_thread::get_id() << " 生产:" << index << std::endl;
			buffer.push(index++);
			std::this_thread::sleep_for(std::chrono::milliseconds(300));
		}
		consumer_condition.notify_all();
	}
}

void do_consume()
{
	while (true)
	{
		{
			std::unique_lock<std::mutex> lock(buffer_mutex);
			consumer_condition.wait(lock, [&]() {return !buffer.empty(); });
			int element = buffer.front();
			buffer.pop();
			std::cout << std::this_thread::get_id() << " 消费:" << element << ", 剩余:" << buffer.size() << std::endl;
			std::this_thread::sleep_for(std::chrono::milliseconds(500));
		}
		producer_condition.notify_one();
	}
}


void test()
{
	std::thread producer(do_produce);
	std::thread consumer1(do_consume);
	std::thread consumer2(do_consume);

	producer.join();
	consumer1.join();
	consumer2.join();
}


int main()
{
	test();
	return EXIT_SUCCESS;
}
#endif

3. 其他函数

未经允许不得转载:一亩三分地 » C++ std::condition_variable 条件变量
评论 (0)

2 + 7 =