--------------------------------------------------------------------------------
標題: 隊列和事件的配合使用示例
作者: 葉飛虎
日期: 2009.09.09
--------------------------------------------------------------------------------
一個線程收到事件或消息后直接加入到隊列,而處理線程讀取隊列中的事件或消息,并
加以處理。在這個模式中,有一個線程負責寫,多個處理線程讀自己的隊列并處理。雖然看
起來象是一寫多讀,其實不然,針對某一事件隊列而言,只有一個線程是寫一個線程是讀。
隊列和事件的配合使用示例如下:
1 /* 方法一: 獨立線程處理隊列 */
2
3 // 線程執行體
4 void TDealThread::Execute()
5 {
6 // 初始化
7 Longword dwNo;
8 Longword dwCount;
9 TItem* pItem;
10
11 // 線程循環體
12 while (!Terminated())
13 {
14 // 等待事件
15 FEvent->Wait(INFINITE);
16
17 // 循環處理事件項
18 dwCount = FQueue->Count();
19 for (dwNo = 0; !Terminated() && (dwNo < dwCount); dwNo++)
20 {
21 pItem = (TItem*)FQueue->Pop();
22 if (pItem != NULL)
23 {
24 // 處理事件項
25 // ???

26
27 // 釋放項
28 delete pItem;
29 }
30 }
31 }
32 }
33
34 // 添加事件
35 bool TDealThread::AddEvent(const TItem& AItem)
36 {
37 // 初始化
38 bool result = false;
39
40 // 判斷線程是否未終止
41 if (!Terminated())
42 {
43 // 初始化
44 TItem* pItem;
45
46 // 新建項
47 pItem = new TItem;
48 *pItem = AItem;
49
50 // 加入隊列
51 if (FQueue->Push(pItem))
52 {
53 // 事件置位
54 FEvent->Set();
55 result = true;
56 }
57 else
58 delete pItem;
59 }
60
61 // 返回結果
62 return result;
63 }
64
65 // 關閉線程
66 void TDealThread::Close()
67 {
68 // 置終止標志
69 Terminate();
70 FEvent->Set();
71
72 // 喚醒休眠線程
73 if (!Finished() && Suspended())
74 Resume();
75 }
76
77 /* 方法二: 外部線程處理 */
78
79 // 外部線程取事件
80 bool TOwnerObj::GetEvent(TItem& AItem, Longword ATimeout)
81 {
82 // 先取隊列項
83 bool result = GetItem(AItem);
84
85 // 判斷是否需要等待
86 if (!result && (ATimeout != 0))
87 {
88 // 初始化
89 Longword dwBegin = GetTickCount();
90
91 // 循環等待事件
92 while (GetTickCount() - dwBegin < ATimeout)
93 {
94 // 防止其它多線程讀取時信號取不到, 50 毫秒等待
95 FEvent->Wait(50);
96
97 // 取隊列項
98 if (GetItem(AItem))
99 {
100 result = true;
101 break;
102 }
103 }
104 }
105
106 // 返回結果
107 return result;
108 }
109
110 // 添加事件
111 bool TOwnerObj::AddEvent(const TItem& AItem)
112 {
113 // 初始化
114 bool result = false;
115 TItem* pItem;
116
117 // 新建項
118 pItem = new TItem;
119 *pItem = AItem;
120
121 // 加入隊列
122 if (FQueue->Push(pItem))
123 {
124 // 事件置位
125 FEvent->Set();
126 result = true;
127 }
128 else
129 delete pItem;
130
131 // 返回結果
132 return result;
133 }
134
135 // 取隊列項
136 bool TOwnerObj::GetItem(TItem& AItem)
137 {
138 // 初始化
139 TItem* pItem;
140 bool result = false;
141
142 // 判斷隊列是否非空
143 while (FQueue->Count() != 0)
144 {
145 pItem = (TItem*)FQueue->Pop();
146 if (pItem != NULL)
147 {
148 AItem = *pItem;
149 result = true;
150
151 // 釋放項
152 delete pItem;
153 break;
154 }
155 }
156
157 // 返回結果
158 return result;
159 }
160
posted on 2011-05-22 11:08
Kyee Ye 閱讀(247)
評論(0) 編輯 收藏 引用 所屬分類:
技巧雜集