c++11条件变量和互斥锁

1:写一个链表

2:如果超过固定大小push阻塞

3:如果链表为空,pop也会阻塞

直接看代码,
main.cpp

#include <stdio.h>
#include <list>
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>

using namespace std;

class listPack
{
public:
	listPack(int maxSize = 10)
	{
		this->_maxSize = maxSize;
	}

	~listPack()
	{
		// 释放链表
	}
	void push(int *mPkt) // 如果链表满,会阻塞
	{
		{
			std::unique_lock<std::mutex> lock{ muxPktVideo };
			conditionMax.wait(lock, [&]()->bool { return listPacks_video.size() < _maxSize; });
		}
		{
			std::unique_lock<std::mutex> lock{ muxPktVideo };

			listPacks_video.push_back(mPkt);
			conditionVideo.notify_one();
		}
	}

	int * pop() // 如果链表空,也会阻塞
	{

		int * t_pkt = 0;
		{
			std::unique_lock<std::mutex> lock{ muxPktVideo };
			//MVideoCap * ptr = this;
			conditionVideo.wait(lock, [&]()->bool { return listPacks_video.size() > 0; });

			t_pkt = listPacks_video.front();
			listPacks_video.pop_front();
			conditionMax.notify_one();
		}
		return t_pkt;
	}

private:

	std::list <int *> listPacks_video;
	std::mutex muxPktVideo;
	std::condition_variable conditionVideo;

	std::condition_variable conditionMax;
	int _maxSize = 10; // 链表的最大长度, 如果等于10 push 的时候会阻塞, 如果等于0 get 的时候会阻塞
};

listPack mListPack(6);

void run(void *prt)
{

	while (1)
	{
		printf("run .... \n");
		int *p = mListPack.pop();

		printf("p[0] = %d \n", p[0]);

		std::this_thread::sleep_for(std::chrono::milliseconds(1000));
		delete p;
	}
}

int main()
{
	std::thread th(run, (void*)(NULL));

	for (int i = 0; i < 100; i++)
	{
		int * p = new int[1];
		*p = i;

		mListPack.push(p);

		printf("hello i = %d \n", i);
	}
	th.join();

}

用模板来写这个链表类似乎更通用一些
main.cpp

#include <stdio.h>
#include <list>
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>

using namespace std;

template<typename T>
class TaskQueueMax {
public:
	TaskQueueMax(int maxSize=10)
	{
		this->_maxSize = maxSize;
	}
	//打入任务至列队
	template<typename C>
	void push_task(C &&task_func) {

		{
			unique_lock<decltype(_mutex)> lock{ _mutex };
			_conditionMax.wait(lock, [&]()->bool { return _queue.size() < _maxSize; }); // suspend and wait ...
		}
		{
			lock_guard<decltype(_mutex)> lock(_mutex);
			_queue.emplace_back(std::forward<C>(task_func));
			_condition.notify_one();
		}

	}
	template<typename C>
	void push_task_first(C &&task_func) {

		{
			unique_lock<decltype(_mutex)> lock{ _mutex };
			_conditionMax.wait(lock, [&]()->bool { return _queue.size() < _maxSize; }); // suspend and wait ...
		}
		{
			lock_guard<decltype(_mutex)> lock(_mutex);
			_queue.emplace_front(std::forward<C>(task_func));
			_condition.notify_one();

		}

	}
	//清空任务列队
	void push_exit(unsigned int n) {

	}
	//从列队获取一个任务,由执行线程执行
	bool get_task(T &tsk) {

		unique_lock<decltype(_mutex)> lock(_mutex);

		_condition.wait(lock, [&]()->bool { return _queue.size() > 0; }); // suspend and wait ...

	 //改成右值引用后性能提升了1倍多!
		tsk = std::move(_queue.front());
		_queue.pop_front();
		_conditionMax.notify_one();
		return true;
	}
	uint64_t size() const {
		lock_guard<decltype(_mutex)> lock(_mutex);
		return _queue.size();
	}
private:

	std::list<T> _queue;
	mutable mutex _mutex;
	std::condition_variable _condition;
	std::condition_variable _conditionMax;
	int _maxSize;

};

TaskQueueMax<int *> mTaskQueue(10);
void run(void *prt)
{
	while (1)
	{
		printf("run .... \n");

		int * p = 0;
		mTaskQueue.get_task(p);
		
		printf("p[0] = %d \n", p[0]);

		std::this_thread::sleep_for(std::chrono::milliseconds(1000));

		delete p;

	}
}
int main()
{
	std::thread th(run, (void*)(NULL));

	for (int i = 0; i < 100; i++)
	{
		int * p = new int[1];
		*p = i;
		mTaskQueue.push_task(p);
		printf("hello i = %d \n", i);


	}

	th.join();

}

不限制链表长度

#include <stdio.h>
#include <list>
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>

using namespace std;

template<typename T>
class TaskQueueMax {
public:
	TaskQueueMax()
	{

	}
	//打入任务至列队
	template<typename C>
	void push_task(C &&task_func) {
		{
			lock_guard<decltype(_mutex)> lock(_mutex);
			_queue.emplace_back(std::forward<C>(task_func));
			_condition.notify_one();
		}

	}
	template<typename C>
	void push_task_first(C &&task_func) {

		{
			lock_guard<decltype(_mutex)> lock(_mutex);
			_queue.emplace_front(std::forward<C>(task_func));
			_condition.notify_one();

		}

	}
	//清空任务列队
	void push_exit(unsigned int n) {

	}
	//从列队获取一个任务,由执行线程执行
	bool get_task(T &tsk) {

		unique_lock<decltype(_mutex)> lock(_mutex);

		_condition.wait(lock, [&]()->bool { return _queue.size() > 0; }); // suspend and wait ...
															  //改成右值引用后性能提升了1倍多!
		tsk = std::move(_queue.front());
		_queue.pop_front();
		return true;
	}
	uint64_t size() const {
		lock_guard<decltype(_mutex)> lock(_mutex);
		return _queue.size();
	}
private:

	std::list<T> _queue;
	mutable mutex _mutex;
	std::condition_variable _condition;
};

TaskQueueMax<int *> mTaskQueue;
void run(void *prt)
{
	while (1)
	{
		printf("run .... \n");

		int * p = 0;
		mTaskQueue.get_task(p);

		printf("p[0] = %d \n", p[0]);

		std::this_thread::sleep_for(std::chrono::milliseconds(1000));

		delete p;

	}
}
int main()
{
	std::thread th(run, (void*)(NULL));

	for (int i = 0; i < 100; i++)
	{
		int * p = new int[1];
		*p = i;
		mTaskQueue.push_task(p);
		printf("hello i = %d \n", i);


	}

	th.join();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值