无锁环形队列

  • 1.Ring_Queue在payload前加入一个头,来表示当前节点的状态
  • 2.当前节点的状态包括可以读、可以写、正在读、正在写
  • 3.当读完成后将节点状态改为可以写,当写完成后将节点状态改为可以读
  • 4.Ring_Queue使用时参照生产者消费者模型,生产者生产(写)一个可用节点,消费者获得(读)队列头节点

Github地址: https://github.com/HITFishily/CandCPP

/**************************************************************************************************
* File Name : ring_queue_nolock.h
* Created : 20 / 02 / 10
* Author : GYT
* Description : 无锁环形队列
* 1.Ring_Queue在payload前加入一个头,来表示当前节点的状态
* 2.当前节点的状态包括可以读、可以写、正在读、正在写
* 3.当读完成后将节点状态改为可以写,当写完成后将节点状态改为可以读
* 4.Ring_Queue使用时参照生产者消费者模型,生产者生产(写)一个可用节点,消费者获得(读)队列头节点
**************************************************************************************************/
#include <assert.h>
#include <string.h>
#include <sys/types.h> typedef unsigned char u_char; #define CAN_WRITE 0x00
#define CAN_READ 0x01
#define READING 0x02
#define WRITING 0x03 typedef struct tag
{
u_char tag_value;
}TAG; class Ring_Queue
{
public:
/**************************************************************************************************
* Function Name : Ring_Queue
* Description : 构造函数
* Date : 20 / 02 / 10
* Parameter : int nmemb:队列大小 int size:Payload长度
* Return Code : none
* Author : GYT
**************************************************************************************************/
Ring_Queue(int nmemb, int size):m_inmemb(nmemb), m_isize(size)
, m_iread_now(0), m_iwrite_now(0)
{
if (nmemb <= 0 || size <= 0)
{
assert(0);
}
m_queue_p = NULL;
m_queue_p = new u_char[nmemb * (sizeof(TAG)+size)];
memset(m_queue_p, 0, nmemb * (sizeof(TAG)+size));
}
/**************************************************************************************************
* Function Name : Ring_Queue
* Description : 析构函数
* Date : 20 / 02 / 10
* Parameter : none
* Return Code : none
* Author : GYT
**************************************************************************************************/
~Ring_Queue()
{
if (m_queue_p) delete[]m_queue_p; }
/**************************************************************************************************
* Function Name : Read
* Description : 读取函数
* Date : 20 / 02 / 10
* Parameter : none
* Return Code : 指向payload的指针
* Author : GYT
**************************************************************************************************/
u_char * Read();
/**************************************************************************************************
* Function Name : Read_Over
* Description : 读取之后的操作,将节点状态跟更新为‘可以写’,并将可读节点指向下一个位置
* Date : 20 / 02 / 10
* Parameter : none
* Return Code : none
* Author : GYT
**************************************************************************************************/
void Read_Over();
/**************************************************************************************************
* Function Name : Write
* Description : 写入函数
* Date : 20 / 02 / 10
* Parameter : none
* Return Code : 此时返回一个安全的、可以用来写数据的指针,具体的写入操作由生产者执行
* Author : GYT
**************************************************************************************************/
u_char * Write();
/**************************************************************************************************
* Function Name : Write_Over
* Description : 写入之后的操作,将节点状态跟更新为‘可以读’,并将可写节点指向下一个位置
* Date : 20 / 02 / 10
* Parameter : none
* Return Code : none
* Author : GYT
**************************************************************************************************/
void Write_Over();
private:
/**************************************************************************************************
* Function Name : queue_peek_nth
* Description : 因为整个队列是u_char数组,需要根据字节数偏移至指定位置
* Date : 20 / 02 / 10
* Parameter : u_char *queue_p:队列 int pos:需要偏移的位置
* Return Code : none
* Author : GYT
**************************************************************************************************/
u_char *queue_peek_nth(u_char *queue_p, int pos);
u_char* m_queue_p; //队列指针
int m_inmemb; //队列大小
int m_isize; //队列中存放数据的长度
volatile int m_iread_now; //当前可读节点
volatile int m_iwrite_now; //当前可写节点
};
#include "ring_queue_nolock.h"

u_char * Ring_Queue::Read()
{
u_char * g_p = 0;
TAG * tag_p = 0;
u_char *user_data = 0; g_p = queue_peek_nth(m_queue_p, m_iread_now);
tag_p = (TAG *)g_p;
if (tag_p->tag_value == CAN_READ)
{
user_data = (u_char *)g_p + sizeof(TAG);
tag_p->tag_value = READING;
}
return user_data;
} void Ring_Queue::Read_Over()
{
u_char * g_p = 0;
TAG * tag_p = 0; g_p = queue_peek_nth(m_queue_p, m_iread_now);
tag_p = (TAG *)g_p;
if (tag_p->tag_value == READING)
{
tag_p->tag_value = CAN_WRITE;
m_iread_now = (m_iread_now + 1) % m_inmemb;
}
} u_char * Ring_Queue::Write()
{
u_char * g_p = 0;
TAG * tag_p = 0;
u_char *user_data = 0; g_p = queue_peek_nth(m_queue_p, m_iwrite_now);
tag_p = (TAG *)g_p;
if (tag_p->tag_value == CAN_WRITE)
{
user_data = (u_char *)g_p + sizeof(TAG);
tag_p->tag_value = WRITING;
}
return user_data;
} void Ring_Queue::Write_Over()
{
u_char * g_p = 0;
TAG * tag_p = 0; g_p = queue_peek_nth(m_queue_p, m_iwrite_now);
tag_p = (TAG *)g_p;
if (tag_p->tag_value == WRITING)
{
tag_p->tag_value = CAN_READ;
m_iwrite_now = (m_iwrite_now + 1) % m_inmemb;
}
} u_char* Ring_Queue::queue_peek_nth(u_char *queue_p, int pos)
{
u_char *rst = 0;
if (queue_p && pos < m_inmemb)
{
rst = queue_p + pos * (sizeof(TAG)+m_isize);
}
return rst;
}

最新文章

  1. 解决magento后台无法登陆/登陆没有反应的方法
  2. Java-URL类详解
  3. Java bean validation 规范与参考实现
  4. Apache Spark源码走读之7 -- Standalone部署方式分析
  5. Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的联系
  6. postgresql plpythonu例子
  7. aop郁闷错误
  8. HD2029
  9. 【BZOJ3196】Tyvj 1730 二逼平衡树
  10. [Android分享] 彻底理解ldpi、mdpi、hdpi、xhdpi、xxhdpi
  11. Ionic 测试针对Andorid平台
  12. mysql 基础之CURD
  13. Maven-项目构建技术(工具)
  14. Hibernate常见问题 No row with the given identifier exists问题的解决办法及解决
  15. JS实现2048代码
  16. java数组冒泡排序
  17. Codeforces Round #529 (Div. 3) D. Circular Dance
  18. SIOCGMIIPHY 和 SIOCSMIIREG 命令
  19. [转]mysql使用关键字作为列名的处理方式
  20. 测量应用程序cass和cad的使用感受

热门文章

  1. python 网络爬虫(三)
  2. 服务端OLEVARIANT数据之后传输
  3. python之字符串,列表,字典,元组,集合内置方法总结
  4. keep-alive 用法 及activated,deactivated这两个生命周期函数
  5. 吴裕雄--天生自然HADOOP学习笔记:hadoop集群实现PageRank算法实验报告
  6. Linux下搭建一个nginx+2tomcat负载均衡环境(转)
  7. vue.js使用更简单的方法制作带删除功能的tooolist
  8. ubuntu16.04 使用tensorflow object detection训练自己的模型
  9. .net高手:forms验证中中&lt;forms loginUrl=&quot;&quot; defaultUrl=&quot;&quot;&gt;defaulturl和loginurl的区别
  10. 【Python数组及其基础操作】【numpy ndarray】