再谈Selector的wakeup方法

    xiaoxiao2024-03-21  114

    过去推荐过两篇blog《Java NIO类库Selector机制解析》( 上, 下),感叹java为了跨平台似乎“很傻很天真”。最近学习使用ACE,才知道这个解决办法倒不是java开创的,ACE也是这样搞的。java nio中Selector的wakeup方法,类似于ACE_Select_Reactor的notify机制,可以从非select调用的线程去唤醒阻塞在select调用上的select线程,当然ACE_Select_Reactor的notify强大多了,可以实现event handler的无限扩容。ACE_Select_Reactor的notify的实现是通过ACE_Pipe,在ACE_Pipe中可以清晰地看到针对win32平台是采用了TCP连接: #if  defined (ACE_LACKS_SOCKETPAIR) || defined (__Lynx__)   ACE_INET_Addr my_addr;   ACE_SOCK_Acceptor acceptor;   ACE_SOCK_Connector connector;   ACE_SOCK_Stream reader;   ACE_SOCK_Stream writer;    int  result  =   0 ; #  if  defined (ACE_WIN32)   ACE_INET_Addr local_any  (static_cast < u_short >  ( 0 ), ACE_LOCALHOST); #  else   ACE_Addr local_any  =  ACE_Addr::sap_any; # endif  /*  ACE_WIN32  */    //  Bind listener to any port and then find out what the port was.    if  (acceptor.open (local_any)  ==   - 1        ||  acceptor.get_local_addr (my_addr)  ==   - 1 )     result  =   - 1 ;    else     {       ACE_INET_Addr sv_addr (my_addr.get_port_number (),                              ACE_LOCALHOST);        //  Establish a connection within the same process.        if  (connector.connect (writer, sv_addr)  ==   - 1 )         result  =   - 1 ;        else   if  (acceptor.accept (reader)  ==   - 1 )         {           writer.close ();           result  =   - 1 ;         }     }    //  Close down the acceptor endpoint since we don't need it anymore.   acceptor.close ();

        在类unix平台是采用STREAMS管道,在一些遗留的unix平台上是socketpair()。为什么在win32上采用TCP连接的方式呢?原因不是什么性能、资源问题,也不是因为windows管道消耗的资源比tcp多,而是由于winsock的select函数(java nio的select在win32下是使用select实现的)是无法监测管道事件的,也就是说无法将windows管道加入到fd_set中,为了做到可移植,才在win32上采用了TCP连接的方式来实现。这一点在blog上篇的新回复中已经有人提到。

    文章转自庄周梦蝶  ,原文发布时间2009-02-01

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)