一读一写情况下,无锁环形队列如何实现?
无锁环形队列的设计及示例,读写队列最大的应用是:一个线程收到事件或消息后直接
加入到队列,而处理线程读取队列中的事件或消息,并加以处理。在这个模式中,有一个线
程负责写,多个处理线程读自己的队列并处理。虽然看起来象是一写多读,其实不然,针对
某一事件队列而言,只有一个线程是写一个线程是读。
环形一读一写队列中,不需要担心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
补充:综合编程 , 其他综合 ,