smart queue

来源:互联网 发布:淘宝商品降权多久恢复 编辑:程序博客网 时间:2024/06/13 22:43
/*************************************************************************    > 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 valuepublic:AtomicInteger():value(0){}/* * @brief get the original value  * */T GetValue() {// if value == 0 then value = 0 and return the original valuereturn __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);}};//nstypedef 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 lockpublic: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 variablesvolatile 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 queueQueueNode<DataType>*m_pNext;            // the next pointerpublic: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

0 0
原创粉丝点击