linux c/c++ 后台开发常用组件之:高性能阻塞队列

看这个之前不懂 互斥锁和条件变量的,请看这两篇文章

①重点讲解互斥锁,也讲解了条件变量https://www.jianshu.com/p/e1334db7113a

②讲解条件变量 https://www.cnblogs.com/jiu0821/p/6424951.html

阻塞队列是后台开发中多线程异步架构的基本数据结构,像python, java 都提供线程安全的阻塞队列,c++ 可能需要自己实现一个模板。

从性能考虑,自己没有使用STL的queue作为基本数据结构,而是使用循环数组作为基本数据结构,性能应该比queue高,省去了动态内存分配和回收。

缺点就是,队列大小不可动态扩展,当时实际开发中,可以通过压力测试和内存的限制,配置合适的队列大小来满足应用需求。
 

 
#ifndef BLOCK_QUEUE_H
#define BLOCK_QUEUE_H
 
#include <iostream>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
using namespace std;
 
template<class T>
class block_queue
{
	public:
		block_queue(int max_size = 1000)
		{
			if(max_size <= 0)
			{
				exit(-1);
			}
			
			m_max_size = max_size;
			m_array = new T[max_size];
			m_size = 0;
			m_front = -1;
			m_back = -1;
 
			m_mutex = new pthread_mutex_t;
			m_cond = new pthread_cond_t;
			pthread_mutex_init(m_mutex, NULL);
			pthread_cond_init(m_cond, NULL);
		}
 
		void clear()
		{
			pthread_mutex_lock(m_mutex);
			m_size = 0;
			m_front = -1;
			m_back = -1;
			pthread_mutex_unlock(m_mutex);
		}
 
		~block_queue()
		{
			pthread_mutex_lock(m_mutex);
			if(m_array != NULL)
				delete  m_array;
			pthread_mutex_unlock(m_mutex);
 
			pthread_mutex_destroy(m_mutex);
			pthread_cond_destroy(m_cond);
 
			delete m_mutex;
			delete m_cond;
		}
 
		bool full()const
		{
			pthread_mutex_lock(m_mutex);
			if(m_size >= m_max_size)
			{
				pthread_mutex_unlock(m_mutex);
				return true;
			}
			pthread_mutex_unlock(m_mutex);
			return false;
		}
 
		bool empty()const
		{
			pthread_mutex_lock(m_mutex);
			if(0 == m_size)
			{
				pthread_mutex_unlock(m_mutex);
				return true;
			}
			pthread_mutex_unlock(m_mutex);
			return false;
		}
		
		bool front(T& value)const
		{
			pthread_mutex_lock(m_mutex);
			if(0 == m_size)
			{
				pthread_mutex_unlock(m_mutex);
				return false;
			}
			value = m_array[m_front];
			pthread_mutex_unlock(m_mutex);
			return true;
		}
		
		bool back(T& value)const
		{
			pthread_mutex_lock(m_mutex);
			if(0 == m_size)
			{
				pthread_mutex_unlock(m_mutex);
				return false;
			}
			value = m_array[m_back];
			pthread_mutex_unlock(m_mutex);
			return true;
		}
 
		int size()const
		{
			int tmp = 0;
			pthread_mutex_lock(m_mutex);
			tmp = m_size;
			pthread_mutex_unlock(m_mutex);
			return tmp;
		}
 
		int max_size()const
		{
			int tmp = 0;
			pthread_mutex_lock(m_mutex);
			tmp = m_max_size;
			pthread_mutex_unlock(m_mutex);
			return tmp;
		}
 
		bool push(const T& item)
		{
			pthread_mutex_lock(m_mutex);
			if(m_size >= m_max_size)
			{
				pthread_cond_broadcast(m_cond);
				pthread_mutex_unlock(m_mutex);
				return false;
			}
			
			m_back = (m_back + 1) % m_max_size;
			m_array[m_back] = item;
 
			m_size++;
			pthread_cond_broadcast(m_cond);
			pthread_mutex_unlock(m_mutex);
 
			return true;
		}
 
		bool pop(T& item)
		{
			pthread_mutex_lock(m_mutex);
			while(m_size <= 0)
			{
				if(0 != pthread_cond_wait(m_cond, m_mutex))
				{
					pthread_mutex_unlock(m_mutex);
					return false;
				}
			}
 
			m_front = (m_front + 1) % m_max_size;
			item = m_array[m_front];
			m_size--;
			pthread_mutex_unlock(m_mutex);
			return true;
		}
 
		bool pop(T& item, int ms_timeout)
		{
			struct timespec t = {0,0};
			struct timeval now = {0,0};
			gettimeofday(&now, NULL);
			pthread_mutex_lock(m_mutex);
			if(m_size <= 0)
			{
				t.tv_sec = now.tv_sec + ms_timeout/1000;
				t.tv_nsec = (ms_timeout % 1000)*1000;
				if(0 != pthread_cond_timedwait(m_cond, m_mutex, &t))
				{
					pthread_mutex_unlock(m_mutex);
					return false;
				}
			}
 
			if(m_size <= 0)
			{
				pthread_mutex_unlock(m_mutex);
				return false;
			}
 
			m_front = (m_front + 1) % m_max_size;
			item = m_array[m_front];m_size--;
			pthread_mutex_unlock(m_mutex);
			return true;
		}
 
private:
		pthread_mutex_t *m_mutex;
		pthread_cond_t *m_cond;
		T *m_array;
		int m_size;
		int m_max_size;
		int m_front;
		int m_back;
};
 
#endif

测试程序:

#include<iostream>
#include"block_queue.h"
using namespace std;
 
block_queue<int> g_queue(100);
void *p(void *args)
{
	sleep(1);
	int data = 0;
	for(int i = 0; i < 100; i++)
	{
		g_queue.push(data++);
	}
	return NULL;
}
 
void *c(void* args)
{
	while(true)
	{
		int t = 0;
		if(!g_queue.pop(t,1000))
		{
			cout<<"timeout"<<endl;
			continue;
		}
		else
		{
			cout<<t<<endl;
		}
		g_queue.pop(t);
		cout<<"block="<<t<<endl;
	
	}
 
	return NULL;
}
 
int main()
{
	pthread_t id;
	pthread_create(&id, NULL, p, NULL);
	//pthread_create(&id, NULL, p, NULL);
	//pthread_create(&id, NULL, c, NULL);
	pthread_create(&id, NULL, c, NULL);
	for(;;)sleep(1);
	return 0;
}

上述转载于:https://blog.csdn.net/coder_yi_liu/article/details/41093453

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值