一读一写情况下,无锁环形队列如何实现?

来源:互联网 发布:淘宝优惠卷在哪领 编辑:程序博客网 时间:2024/06/05 09:54
一读一写情况下,无锁环形队列如何实现?

--------------------------------------------------------------------------------
标题: 一读一写情况下,无锁环形队列如何实现?
作者: 叶飞虎
日期: 2009.03.09
--------------------------------------------------------------------------------

   无锁环形队列的设计及示例,读写队列最大的应用是:一个线程收到事件或消息后直接
加入到队列,而处理线程读取队列中的事件或消息,并加以处理。在这个模式中,有一个线
程负责写,多个处理线程读自己的队列并处理。虽然看起来象是一写多读,其实不然,针对
某一事件队列而言,只有一个线程是写一个线程是读。

   环形一读一写队列中,不需要担心unsigned long溢出问题,因为溢出后自动回归,相减
值还会保留。

 

  1 示例一(注:Max_Count 必须为 2 的指数,即:2, 4, 8, 16):
  2 
  3 // 队列尺寸
  4 #define Max_Count    4096
  5 #define Max_Mask     4095     // = Max_Count - 1
  6 
  7 // 变量
  8 void*          List[Max_Count];
  9 unsigned long  Push_Count;
 10 unsigned long  Pop_Count;
 11 
 12 // 初始化队列
 13 void InitQueue()
 14 {
 15    Push_Count  = 0;
 16    Pop_Count   = 0;
 17    memset(List, 0, sizeof(List));
 18 }
 19 
 20 // 加入
 21 bool Push(void* AData)
 22 {
 23    if (Push_Count - Pop_Count < Max_Count)
 24    {
 25       List[Push_Count & Max_Mask] = AData;
 26       Push_Count++;
 27       return true;
 28    }
 29    else
 30       return false;
 31 }
 32 
 33 // 取出
 34 void* Pop()
 35 {
 36    // 初始化
 37    void* result = NULL;
 38 
 39    // 判断是否为空
 40    if (Push_Count != Pop_Count)
 41    {
 42       result = List[Pop_Count & Max_Mask];
 43       Pop_Count++;
 44    }
 45 
 46    // 返回结果
 47    return result;
 48 }
 49 
 50 示例二(注:Max_Count >= 2):
 51 
 52 // 队列尺寸
 53 #define Max_Count    4096
 54 #define High_Index   4095     // = Max_Count - 1
 55 
 56 // 变量
 57 void*          List[Max_Count];
 58 unsigned long  Push_Count;
 59 unsigned long  Push_Index;
 60 unsigned long  Pop_Count;
 61 unsigned long  Pop_Index;
 62 
 63 // 初始化队列
 64 void InitQueue()
 65 {
 66    Push_Count  = 0;
 67    Push_Index  = 0;
 68    Pop_Count   = 0;
 69    Pop_Index   = 0;
 70    memset(List, 0, sizeof(List));
 71 }
 72 
 73 // 加入
 74 bool Push(void* AData)
 75 {
 76    if (Push_Count - Pop_Count < Max_Count)
 77    {
 78       List[Push_Index] = AData;
 79       Push_Count++;
 80       if (Push_Index == High_Index)
 81          Push_Index = 0;
 82       else
 83          Push_Index++;
 84 
 85       return true;
 86    }
 87    else
 88       return false;
 89 }
 90 
 91 // 取出
 92 void* Pop()
 93 {
 94    // 初始化
 95    void* result = NULL;
 96 
 97    // 判断是否为空
 98    if (Push_Count != Pop_Count)
 99    {
100       result = List[Pop_Index];
101       Pop_Count++;
102       if (Pop_Index == High_Index)
103          Pop_Index = 0;
104       else
105          Pop_Index++;
106    }
107 
108    // 返回结果
109    return result;
110 }
111 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 虾缸的过滤吸虾怎么办 加热棒坏了鱼怎么办 钢材软打孔断钻头怎么办 空调余额下水管检查口按不上怎么办 风机盘管噪音大怎么办 混凝土水泥放少了怎么办 门式钢梁端板连接下料短啦怎么办? 灌桩导管堵了怎么办 公路车尾钩歪了怎么办 铃木羚羊车大灯不亮怎么办 玻璃瓶打碎了里面食物怎么办 玻璃门上轴坏了怎么办 配筋面积小了怎么办 ps大文件存不了怎么办 挑架钢丝绳拉环未预埋怎么办 出现偏拉的梁怎么办 尾插不好上锡怎么办 汽车玻璃上的焊点很难去除怎么办 拆苹果硬盘焊点掉了怎么办 玻璃被电焊滴到怎么办 gta5特质卡宾装了消音器怎么办 联想V形底座不好用怎么办 华为手环不计步怎么办 小米手环不计步怎么办 小米手环骑自行车不计步数怎么办 放逐之城着火了怎么办 城市天际线地价过低怎么办 放逐之城铁采完怎么办 车钥匙反锁车内怎么办 眼镜用热水洗了怎么办 眼镜放平后眼镜腿不平怎么办 瞄准镜十字歪了怎么办 瞄准镜调到底了怎么办 墨镜镜片刮花了怎么办 usb小风扇不转怎么办 金属眼镜压歪了怎么办 眼镜被电焊打了怎么办 电焊闪的眼睛疼怎么办 烧了电焊眼睛疼怎么办 用了电焊眼睛痛怎么办 烧电焊脸上红痛怎么办