服务器端软件的一种设计

 服务器端软件的复杂度相对比较高。30000多行代码的中间件软件的主线程程序又是怎样的呢?

        小鸡射手在实际工作中设计的网络服务的主线程代码如下:

IContext &  context  =  ContextManager::GetContext();
IEventHandler
&  handler  =  EventHandlerManager::GetEventHandler();
while ( ! IsStopped())
{
        IEvent
* event = context.eventQueue.GetEvent(context.configSetting.eventQueueTimeout);
        
if(event==0continue;

        
{
                
const auto_ptr<IEvent> pEvent(event);
                
try
                
{
                         
event->Handle(handler, context);
                 }

                 
catch(const exception& ex)
                 
{
                          context.logger.Error(
"Dispatcher中发现异常:[%s]。", ex.what());
                  }

                  
catch(...)
                 
{
                           context.logger.Error(
"Dispatcher中发现未知异常。EventID is [%s]"event->GetInfo());
                 }

         }

}

        这段代码应该还是比较好理解的,eventQueue采用stl queue加上线程同步机制实现。其中涉及到的两个关键接口定义如下:

class  IEvent  {
public:
        
virtual ~IEvent()    {}
           
virtual void    Handle(IEventHandler& handler, IContext& context)=0;
           
virtual const char*    GetInfo()=0;
}
;

class  IEventHandler  {
public:    
        
virtual    ~IEventHandler() {}
        
virtual    void Handle(ThisEvent& event, IContext& context){}
        
virtual    void Handle(ThatEvent& event, IContext& context){}
        
virtual    void Handle(OtherEvent& event, IContext& context){}
}

        设计的灵感来自于:

  •  Windows的消息机制。早期的Windows开发主程序就是GetMessage和switch循环,所以以上程序只是对此思想的Object Oriented版本;
  • Think in Java对垃圾分类的讨论,垃圾分类问题可以通过Visitor模式解决。下面就是采用该模式实现的具体event类的Handle方法。应用逻辑则是在IEventHandler的子类中实现。
void    ThisEvent::Handle(IEventHandler &  handler, IContext &  context)
{
        handler.Handle(
*this, context);
}

          该设计的优点是:

  • 尽管服务器端的软件往往是多线程的,需要线程间同步。但是由于该设计的处理均在主线程上完成,故eventHandler中不需要(或者减少了大量)同步;
  • 软件扩展容易,只要加event和对应的eventhandler;
  •  code on interface,代码接口和实现分离,易于维护。

         当然,该设计也有需要注意的地方:

  • eventHandler中的操作不允许blocking,所以类似写日志这样的操作实际上是放到后台线程完成的。 其中的原因和界面处理程序中长时间操作会导致界面没有反应一样;
  • 理论上,该设计在多CPU的机器上,可能不能完全发挥硬件的潜力。

        总之,这还是不错的设计。小鸡射手已经成功将它运用到公司的两大产品中。


 

你可能感兴趣的:(多线程,exception,windows,服务器,Class,interface)