随笔-3  评论-5  文章-13  trackbacks-0

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

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理