C++11 同步阻塞队列

参考《深入应用C++11》

SyncQueue.cpp

//同步阻塞队列
#include "SyncQueue.h"

using namespace std;

template<class T>
SyncQueue<T>::SyncQueue(int max_size):max_size(max_size)//这里注意类不能少了类型SyncQueue<T>,因为不同的T是不同的类型
{
}

template<class T>
SyncQueue<T>::~SyncQueue()
{
}

template<class T>
void SyncQueue<T>::put(const T& val)
{
	lock_guard<mutex> locker(lock);
	while (isFull())
	{
		cout << "\nQueue is full now, wait a minute!" << endl;
		cv_full.wait(lock);
	}
	q.emplace_back(val);
	cv_empty.notify_one();
}

template<class T>
void SyncQueue<T>::take(T& val)
{
	lock_guard<mutex> locker(lock);
	while (isEmpty())
	{
		cout << "\nQueue is empty now, wait a minute!" << endl;
		cv_empty.wait(lock);
	}
	val = q.front();
	q.pop_front();
	cv_full.notify_one();
}

template<class T>
bool SyncQueue<T>::isEmpty()
{
	return q.size() == 0;
}

template<class T>
bool SyncQueue<T>::isFull()
{
	return q.size() == max_size;
}

template<class T>
int SyncQueue<T>::count()
{
	return q.size();
}

SyncQueue.h

#pragma once
#include<mutex>
#include<condition_variable>
#include<list>
#include<iostream>

using namespace std;

template<class T> class SyncQueue
{
public:
	SyncQueue(int max_size);
	~SyncQueue();
	void put(const T& val);
	void take(T& val);
	bool isEmpty();
	bool isFull();
	int count();

private:
	mutex lock;
	condition_variable_any cv_full, cv_empty;
	list<T> q;
	int size;
	int max_size;
};

条件变量的wait方法会释放互斥量,等到notify再重新获取,所以,当队列存满时,put方法会先释放信号量,等take方法被调用后再获取信号量,然后再入队,当队列为空时,take方法会先释放信号量,等put方法被调用后再获取信号量,然后再出队

测试代码:

#include <thread>
#include <iostream>
#include <future>
#include <chrono>
#include <windows.h>
#include <atomic>
#include "SyncQueue.cpp"//注意这里是cpp

using namespace std;

SyncQueue* q = new SyncQueue(3);
atomic<int> task;

void put()
{
	int i = 6;
	while (i-- > 0)
	{
		q->put(task++);
		cout << "\nput success, size now is " << q->count() << endl;
		this_thread::sleep_for(chrono::seconds(1));
	}
}

void take()
{
	int ret = 0;
	while (true)
	{
		this_thread::sleep_for(chrono::seconds(2));
		q->take(ret);
		cout << "\ntake success, value is: " << ret << endl;
	}
}

int main()
{
	task = 0;
	thread t1(put);
	thread t2(take);
	t1.join();
	t2.join();
	
	system("pause");
	return 0;
}

开启两个线程t1,t2,t1每隔一秒向队列添加一个数,总共添加6个数,t2每隔两秒从队列取一个数

测试结果:

put success, size now is 1

put success, size now is 2

take success, value is: 0

put success, size now is 2

put success, size now is 3

take success, value is: 1

put success, size now is 3

Queue is full now, wait a minute!

take success, value is: 2
put success, size now is 3


take success, value is: 3

take success, value is: 4

take success, value is: 5

Queue is empty now, wait a minute!

发布了17 篇原创文章 · 获赞 22 · 访问量 3039

猜你喜欢

转载自blog.csdn.net/u013536232/article/details/96381025