分类:
2008-10-13 16:11:31
1、Reactor中使用多线程是可以的,看Reactor的代码就知道了,他本来设计得就可以支持多线程的。
不多说了,贴代码先:
我想有了这两个函数,可以把时间执行比较长(如数据库)的操作放到线程里去做。
template <class ACE_SELECT_REACTOR_TOKEN> int
( handle)
{
("ACE_Select_Reactor_T::suspend_handler");
( (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
return this-> (handle);
}
template <class ACE_SELECT_REACTOR_TOKEN> int
( handle)
{
("ACE_Select_Reactor_T::resume_handler");
( (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
return this-> (handle);
}
同理,下面是EPOLL的封装里的代码:
int
ACE_Dev_Poll_Reactor::resume_handler (ACE_HANDLE handle)
{
ACE_TRACE ("ACE_Dev_Poll_Reactor::resume_handler");
ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
return this->resume_handler_i (handle);
}
int
ACE_Dev_Poll_Reactor::handle_events (ACE_Time_Value *max_wait_time)
{
ACE_TRACE ("ACE_Dev_Poll_Reactor::handle_events");
// Stash the current time
//
// The destructor of this object will automatically compute how much
// time elapsed since this method was called.
ACE_MT (ACE_Countdown_Time countdown (max_wait_time));
ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
if (this->deactivated_)
return -1;
// Update the countdown to reflect time waiting for the mutex.
ACE_MT (countdown.update ());
return this->handle_events_i (max_wait_time);
}
这里完全有另外一种派生办法。Reactor里面得到的消息全推到另一个消息队列中去,把他们先suspend,然后做完时再resume,当然,涉及到读写,这不能解决所有的问题。
2、文件句柄的读写:
看过squid代码的可能都知道,就一个线程,但是处理了所有的网络读写和文件读写。
在LINUX下可以直接从ACE_Event_Handle派生出来,跟网络的写法没啥两样,在WIN下比较麻烦,要开线程做,可以参考下面这个函数,他在WIN下面是开了一个辅助线程来做的。
00273 { 00274 #if defined (ACE_WIN32) || defined (ACE_PSOS) 00275 (reactor); 00276 00277 eh-> (reactor); 00278 return thr_mgr-> (&, (void *) eh, flags); 00279 #else 00280 // Keep compilers happy. 00281 (flags); 00282 (thr_mgr); 00283 return reactor-> (, 00284 eh, 00285 ); 00286 #endif /* ACE_WIN32 || ACE_PSOS */ 00287 }