DoubleLockedQueue

来源:互联网 发布:租人软件app 编辑:程序博客网 时间:2024/06/05 07:27
/*************************************************************************    > File Name: DoubleLockedQueue.h    > Author: wangzhicheng    > Mail: 2363702560@qq.com    > Created Time: 2017-01-02    > Statement: double locked concurrent queue ************************************************************************/#ifndef DOUBLE_LOCKED_QUEUE_H#define DOUBLE_LOCKED_QUEUE_H#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <assert.h>#include <atomic>#include <mutex>namespace doublelockedqueue{using namespace std;static const int MAXCAP = 1000000000;/* * the Node of queue * */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 pointerQueueNode() {m_pNext = NULL;}QueueNode(const DataType &data, QueueNode *next = NULL) {m_Data = data;m_pNext = next;}~QueueNode() {m_pNext = NULL;}};/* * double locked queue * */template<class DataType>class DoubleLockedQueue {private:mutex m_Head_Lock;// for dequeuemutex m_Tail_Lock;// for enqueueQueueNode<DataType> *m_pHead;QueueNode<DataType> *m_pTail;atomic<int>m_nNum;             // 用于计数int m_nMaxLen;         // 队列最大长度public:DoubleLockedQueue();/* * @brief 初始化队列容量和头结点 * */void Init(int max);/* * @brief 入队  * @return 入队成功返回true 失败返回false 失败是指队列为满  * */bool EnQueue(const DataType &);/* * @brief 出队 * @return 出队成功返回true 失败返回false 失败是指队列为空 * */bool DeQueue(DataType &);/* * @brief 析构函数 释放头结点 * */~DoubleLockedQueue();};template<class DataType>DoubleLockedQueue<DataType>::DoubleLockedQueue(){m_nNum = 0;}/* * @brief 初始化队列容量和头结点 * */template<class DataType>void DoubleLockedQueue<DataType>::Init(int max) {assert(max > 0 && max <= MAXCAP);m_nMaxLen = max;/*  * generate a head node   * */m_pHead = new QueueNode<DataType>;m_pTail = this->m_pHead;}template<class DataType>bool DoubleLockedQueue<DataType>::EnQueue(const DataType &data) {if(m_nNum.load() >= m_nMaxLen) // 队列满了{return false;}QueueNode<DataType>*p = new QueueNode<DataType>(data);++m_nNum;/*  * 入队与出队的竞争仅仅发生在当队列为空时  * 此时读尾指针与修改尾指针不会同时进行  * 但gcc/g++编译器能够保证对64位地址修改为原子操作   * 例如假设地址A = NULL  * 线程1读取A 线程2修改A  * 那么线程1要么读到NULL 要么读到线程2修改后的地址  * */lock_guard<mutex>lockguard(m_Tail_Lock);m_pTail->m_pNext = p;m_pTail = p;return true;}template<class DataType>bool DoubleLockedQueue<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 emptym_Head_Lock.unlock();return false;}data = newhead->m_Data;m_pHead = newhead;m_Head_Lock.unlock();--m_nNum;  delete p;p = NULL;return true;}template<class DataType>DoubleLockedQueue<DataType>::~DoubleLockedQueue(){delete 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 "DoubleLockedQueue.h"#include <iostream>#include <thread>using namespace doublelockedqueue;DoubleLockedQueue<int>Q;void func0() {while(1){for(int i = 0;i < 10;i++) Q.EnQueue(i);sleep(1);}}void func1() {while(1){int num;if(!Q.DeQueue(num)) {//cerr << "dequeue error...!" << endl;sleep(1);continue;}else cout << "num = " << num << endl;}}int main(){Q.Init(100);thread th1(func0);thread th2(func1);th1.join();th2.join();return 0;}CC=g++all:$(CC) -std=c++11 -g -o DoubleLockedQueueTest main.cpp DoubleLockedQueue.h -pthread -lpthread

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手被皮筋勒肿了怎么办 皮筋把手挤肿了怎么办 猫被皮筋绑久肿了怎么办 抗链0高关节疼怎么办 近视800度老了怎么办 军检体重不达标怎么办 到交房租没有钱怎么办 房租没到期房东要收回怎么办 客户指定发快递我要怎么办? 跨境汇款被退回怎么办 汇款途径写错了怎么办 快递被菜鸟驿站退回怎么办 电脑登录账户已锁定怎么办 被外管局查到境外汇款买房怎么办 军校生复检被刷怎么办 企业私刻章拿去挂项目怎么办? 中通快递被退回怎么办 网易邮箱提示被修复怎么办 小孩屁股烫红了怎么办 8岁近视400度怎么办 部队体能差的人怎么办 上环5天同房了怎么办 肾结石有3mm了怎么办 4*3mm肾结石好痛怎么办 做完肾结石积水后迟续发烧怎么办 血糖高有肾结石反复发高烧怎么办 肾里面有小结石怎么办 大于2厘米的结石怎么办 双肾结石肾盏扩张怎么办 边防消防警卫部队改革义务兵怎么办 汽车年检尾气复检不合格怎么办 车辆年检尾气不合格复检怎么办? 在瓜子上买车复检有问题怎么办 更换车壳车架号怎么办 吸完甲醛的绿萝怎么办 如果公务员复检不合格有异议怎么办 国考公务员政审没有毕业证怎么办 打针硬块4年不消怎么办 外墙补起来难看不好卖怎么办 杠精现实中应该怎么办 发现记者报道假新闻怎么办