smart queue

/*************************************************************************
    > File Name: AtomicInteger.h
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com
    > Created Time: 2017-01-03
    > statement: provide atomic integer and operation for multithread
 ************************************************************************/
#ifndef ATOMIC_INTEGER_H
#define ATMOIC_INTEGER_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
namespace atomicinteger
{
using namespace std;
/**
 *@brief provide atomic integer and operation for multithread
 */
template<class T>
class AtomicInteger 
{
private:
	volatile T value;	// prevent g++ to optimize the value
public:
	AtomicInteger():value(0)
	{
	}
	/*
	 * @brief get the original value 
	 * */
	T GetValue() 
	{
		// if value == 0 then value = 0 and return the original value
		return __sync_val_compare_and_swap(&value, 0, 0);
	}
	/*
	 * @brief suffix ++ such as a++
	 * */
	T operator ++ (int) 
	{
		return __sync_fetch_and_add(&value, 1);
	}
	/*
	 * @brief prefix ++ such as ++a
	 * */
	T operator ++ () 
	{
		return __sync_add_and_fetch(&value, 1);
	}
	/*
	 * @brief 加某个数
	 * */
	T operator + (int num) 
	{
		return __sync_add_and_fetch(&value, num);
	}
	/*
	 * @brief 减某个数
	 * */
	T operator - (int num) 
	{
		return __sync_add_and_fetch(&value, -num);
	}
	/*
	 * @brief suffix -- such as a--
	 * */
	T operator -- (int) 
	{
		return __sync_fetch_and_add(&value, -1);
	}
	/*
	 * @brief prefix -- such as --a
	 * */
	T operator -- () 
	{
		return __sync_add_and_fetch(&value, -1);
	}
	/*
	 * @brief add operation
	 * */
	T operator + (const T &other) 
	{
		return __sync_add_and_fetch(&value, other);
	}
	/*
	 * @brief = operation
	 * */
	T operator = (const T &newValue) 
	{
		return __sync_lock_test_and_set(&value, newValue);
	}
		
};//ns
typedef AtomicInteger<uint64_t>AtomicInt64;
typedef AtomicInteger<uint32_t>AtomicInt32;
}

#endif

/*************************************************************************
    > File Name: ThreadMutex.h
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com
    > Created Time: 2017-01-03
 ************************************************************************/
/*
 * @brief provide a thread mutex 
 * */
#ifndef THREADMUTEX_H
#define THREADMUTEX_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;
namespace threadmutex 
{
#define CAS __sync_bool_compare_and_swap	                // define cas 
/*
 * @brief thread mutex lock
 * */
class ThreadMutexLock 
{
private:
	pthread_mutex_t m_lock;		// mutex lock
public:
	ThreadMutexLock() 
	{
		pthread_mutex_init(&m_lock, NULL);
	}
	~ThreadMutexLock() 
	{
		pthread_mutex_destroy(&m_lock);
	}
	inline void Lock() 
	{
		pthread_mutex_lock(&m_lock);
	}
	inline void UnLock() 
	{
		pthread_mutex_unlock(&m_lock);
	}
};
/*
 * @brief thread cas which is suitable for very short critical zone
 * */
class ThreadCasLock 
{
private:
	// lock variables
	volatile int m_mutex;								
	volatile int m_lock;
	volatile int m_unlock;
	int m_sleeptime;
public:
	ThreadCasLock(int sleeptime = 200) 
	{
		m_mutex = 0;
		m_lock = 1;
		m_unlock = 0;
		m_sleeptime = sleeptime;
	}
	~ThreadCasLock() 
	{
		m_mutex = 0;
		m_lock = 1;
		m_unlock = 0;
	}
	inline void Lock() 
	{
		while(!CAS(&m_mutex, m_unlock, m_lock)) 
		{
			usleep(m_sleeptime);	// wait untill the lock is free usleep(200)
		}
	}
	inline void UnLock() 
	{
		CAS(&m_mutex, m_lock, m_unlock);
	}
};
}
#endif

/*************************************************************************
    > File Name: SmartQueue.h
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com
    > Created Time: 2017-01-03
    > Statement:可限长并发双锁队列 适合多放1出 或多放多出
 ************************************************************************/
#ifndef SMART_QUEUE_H
#define SMART_QUEUE_H
#include <assert.h>
#include "AtomicInteger.h"
#include "ThreadMutex.h"
namespace smartqueue {
using namespace atomicinteger;
using namespace threadmutex;
const static int S_MAXLEN_QUEUE = 100000000;             	    // 该队列结点数上限
/*
 * the Node of queue, the element of Node is pointer
 * */
template<class DataType>
class QueueNode 
{
public:
	DataType m_Data;                        // pointer to the data which needed to be put in the queue
	QueueNode<DataType>*m_pNext;            // the next pointer
public:
	QueueNode() 
	{
		this->m_pNext = NULL;
	}
	QueueNode(const DataType &data, QueueNode *next = NULL)
	{
		this->m_Data = data;
		this->m_pNext = next;
	}
	~QueueNode() 
	{
		this->m_pNext = NULL;
	}
};
/*
 * double locked queue
 * */
template<class DataType>
class SmartQueue
{
private:
	ThreadCasLock m_Head_Lock;      // 适合多放1出
	ThreadCasLock m_Tail_Lock;  
	QueueNode<DataType>*m_pHead;
	QueueNode<DataType>*m_pTail;
	AtomicInt32 m_nNum;             // 用于计数
	int m_nMaxLen;                  // 队列最大长度
public:
	SmartQueue(int sleeptime);
	/*
	 * @brief 初始化队列容量和头结点
	 * */
	void Init(int max);
	/*
	 * @brief 入队 
	 * @return 入队成功返回true 失败返回false 失败是指队列为满 
	 * */
	bool EnQueue(const DataType &);
	/*
	 * @brief 出队
	 * @return 出队成功返回true 失败返回false 失败是队列为空
	 * */
	bool DeQueue(DataType &);
	/*
	 * @brief 判断队列是不是满
	 * @return 满返回true 不满返回false
	 * */
	inline bool Full();
	/*
	 * @brief 判断队列是不是为空
	 * @return 为空返回true 
	 * */
	inline bool Empty();
	/*
	 * @brief 析构函数 释放头结点
	 * */
	~SmartQueue();
};
template<class DataType>
SmartQueue<DataType>::SmartQueue(int sleeptime):m_Head_Lock(sleeptime), m_Tail_Lock(sleeptime)
{
}
/*
 * @brief 初始化队列容量和头结点
 * */
template<class DataType>
void SmartQueue<DataType>::Init(int max) 
{
	assert(max < S_MAXLEN_QUEUE && max > 0);
	m_nMaxLen = max;
	/*
 	 * generate a head node 	
 	 * */
	m_pHead = new QueueNode<DataType>;
	m_pTail = m_pHead;
}
template<class DataType>
bool SmartQueue<DataType>::EnQueue(const DataType &data) 
{
	if(m_nNum.GetValue() >= (unsigned int)(this->m_nMaxLen))	// 队列满了
	{
		return false;	
	}
	QueueNode<DataType>*p = new QueueNode<DataType>(data);
	/*
 	 * 入队与出队的竞争仅仅发生在当队列为空时
 	 * 此时读尾指针与修改尾指针不会同时进行
 	 * 但gcc/g++编译器能够保证对64位地址修改为原子操作 
 	 * 例如假设地址A = NULL
 	 * 线程1读取A 线程2修改A
 	 * 那么线程1要么读到NULL 要么读到线程2修改后的地址
 	 * */
	m_Tail_Lock.Lock();
	m_pTail->m_pNext = p;	
	m_pTail = p;
	m_Tail_Lock.UnLock();
	++this->m_nNum;

	return true;
}
template<class DataType>
bool SmartQueue<DataType>::DeQueue(DataType &data) 
{
	m_Head_Lock.Lock();
	QueueNode<DataType>*p = m_pHead;
	QueueNode<DataType>*newhead = m_pHead->m_pNext;	// 此时取头结点的next指针 可能此时入队修改了头结点的next值 但这两个操作不会并行
	if(!newhead)	// the queue is empty
	{
		m_Head_Lock.UnLock();
		return false;
	}
	data = newhead->m_Data;				
	m_pHead = newhead;
	m_Head_Lock.UnLock();
	--this->m_nNum;  
	delete p;	
	p = NULL;

	return true;
}
template<class DataType>
inline bool SmartQueue<DataType>::Full() 
{
	return m_nNum.GetValue() >= (unsigned int)m_nMaxLen;
} 
template<class DataType>
inline bool SmartQueue<DataType>::Empty() 
{
	return m_nNum.GetValue() <= 0;               // 队列空
}
template<class DataType>
SmartQueue<DataType>::~SmartQueue() 
{
	delete this->m_pHead;
	m_pHead = NULL;
	m_pTail = NULL;
}
}
#endif

/*************************************************************************
    > File Name: main.cpp
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com 
    > Created Time: Sat 31 Dec 2016 09:44:59 AM AWST
 ************************************************************************/

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include "SmartQueue.h"
using namespace std;
using namespace smartqueue;
SmartQueue<int>Q(10);
void func0()
{
	chrono::milliseconds dura(1000);
	while(1)
	{
		for(int i = 0;i < 10;i++) 
		{
			if(!Q.EnQueue(i)) 
			{
				cerr << i << " enqueue failed...!" << endl;
			}
		}
//		this_thread::sleep_for(dura);
	}
}
void func1() 
{
	chrono::milliseconds dura(1);
	while(1)
	{
		int num;
		if(!Q.DeQueue(num)) 
		{
//			cerr << "dequeue failed...!" << endl;
			this_thread::sleep_for(dura);
		}
		else cout << "num = " << num << endl;
	}
}
int main()
{
	Q.Init(5);
	thread th1(func0);
//	thread th2(func1);
	vector<thread>th2s;
	for(int i = 0;i < 100;i++)
	{
		th2s.push_back(thread(func1));
	}
	th1.join();
	for(auto &th:th2s)
	{
		th.join();
	}
//	th2.join();

	return 0;
}

CC=g++
all:
	$(CC) -std=c++11 -g -o ConCurrentQueueTest main.cpp AtomicInteger.h ThreadMutex.h SmartQueue.h -pthread -lpthread

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值