--------------------------------------------------------------------------------
标题: 队列和事件的配合使用示例
作者: 叶飞虎
日期: 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 阅读(235)
评论(0) 编辑 收藏 引用 所属分类:
技巧杂集