--------------------------------------------------------------------------------
標(biāo)題: 一讀一寫情況下,無鎖隊(duì)列如何實(shí)現(xiàn)?
作者: 葉飛虎
日期: 2009.03.09
--------------------------------------------------------------------------------
一讀一寫情況下,無鎖隊(duì)列如何實(shí)現(xiàn)?其實(shí)并不難,先說說一讀一寫無鎖隊(duì)列的實(shí)際應(yīng)
用吧。讀寫隊(duì)列最大的應(yīng)用是:一個線程收到事件或消息后直接加入到隊(duì)列,而處理線程讀
取隊(duì)列中的事件或消息,并加以處理。在這個模式中,有一個線程負(fù)責(zé)寫,多個處理線程讀
自己的隊(duì)列并處理。雖然看起來象是一寫多讀,其實(shí)不然,針對某一事件隊(duì)列而言,只有一
個線程是寫一個線程是讀。
此示例可以封裝成一個Queue類,在KYLib中有TKYQueue類,其實(shí)現(xiàn)原理相同。代碼示例
如下:
1 // 鏈接數(shù)據(jù)項(xiàng)結(jié)構(gòu)
2 typedef struct TLinkItem
3 {
4 void* Data;
5 TLinkItem* Next;
6 } *PLinkItem;
7
8 TLinkItem* FLinkHead; // 隊(duì)列頭
9 TLinkItem* FLinkTail; // 隊(duì)列尾
10
11 // 初始化隊(duì)列
12 void InitQueue()
13 {
14 // 分配隊(duì)列頭項(xiàng)
15 FLinkTail = NULL;
16 FLinkHead = new TLinkItem;
17
18 // 保證 Head 和 Tail 非空, 是一個線程讀一個線程寫的關(guān)鍵!
19 if (FLinkHead != NULL)
20 {
21 // 初始化隊(duì)列頭
22 FLinkHead->Data = NULL;
23 FLinkHead->Next = NULL;
24 FLinkTail = FLinkHead;
25 }
26 else
27 throw;
28 }
29
30 // 加入
31 bool Push(void* AData)
32 {
33 // 初始化
34 bool result = false;
35 TLinkItem* pItem = new TLinkItem;
36
37 // 加入隊(duì)列
38 if (pItem != NULL)
39 {
40 // 寫值
41 pItem->Data = AData;
42 pItem->Next = NULL;
43
44 // 加到末尾
45 FLinkTail->Next = pItem;
46 FLinkTail = pItem;
47
48 // 返回結(jié)果
49 result = true;
50 }
51
52 // 返回結(jié)果
53 return result;
54 }
55
56 // 取出
57 void* Pop()
58 {
59 // 初始化
60 void* result = NULL;
61
62 // 讀取項(xiàng)
63 if (FLinkHead->Next != NULL)
64 {
65 // 取值
66 TLinkItem* pItem = FLinkHead;
67 FLinkHead = FLinkHead->Next;
68 result = FLinkHead->Data;
69
70 // 釋放項(xiàng)
71 delete pItem;
72 }
73
74 // 返回結(jié)果
75 return result;
76 }
77
2 typedef struct TLinkItem
3 {
4 void* Data;
5 TLinkItem* Next;
6 } *PLinkItem;
7
8 TLinkItem* FLinkHead; // 隊(duì)列頭
9 TLinkItem* FLinkTail; // 隊(duì)列尾
10
11 // 初始化隊(duì)列
12 void InitQueue()
13 {
14 // 分配隊(duì)列頭項(xiàng)
15 FLinkTail = NULL;
16 FLinkHead = new TLinkItem;
17
18 // 保證 Head 和 Tail 非空, 是一個線程讀一個線程寫的關(guān)鍵!
19 if (FLinkHead != NULL)
20 {
21 // 初始化隊(duì)列頭
22 FLinkHead->Data = NULL;
23 FLinkHead->Next = NULL;
24 FLinkTail = FLinkHead;
25 }
26 else
27 throw;
28 }
29
30 // 加入
31 bool Push(void* AData)
32 {
33 // 初始化
34 bool result = false;
35 TLinkItem* pItem = new TLinkItem;
36
37 // 加入隊(duì)列
38 if (pItem != NULL)
39 {
40 // 寫值
41 pItem->Data = AData;
42 pItem->Next = NULL;
43
44 // 加到末尾
45 FLinkTail->Next = pItem;
46 FLinkTail = pItem;
47
48 // 返回結(jié)果
49 result = true;
50 }
51
52 // 返回結(jié)果
53 return result;
54 }
55
56 // 取出
57 void* Pop()
58 {
59 // 初始化
60 void* result = NULL;
61
62 // 讀取項(xiàng)
63 if (FLinkHead->Next != NULL)
64 {
65 // 取值
66 TLinkItem* pItem = FLinkHead;
67 FLinkHead = FLinkHead->Next;
68 result = FLinkHead->Data;
69
70 // 釋放項(xiàng)
71 delete pItem;
72 }
73
74 // 返回結(jié)果
75 return result;
76 }
77