再谈Selector的wakeup方法
程序员文章站
2022-03-10 19:45:14
...
过去推荐过两篇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 ();
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上篇的新回复中已经有人提到。
上一篇: oracle存储过程简单示例
推荐阅读
-
Android Selector和Shape的使用方法
-
Android Selector和Shape的使用方法
-
【Java】NIO中Selector的select方法源码分析
-
再谈DOS批处理下格式化日期字符串的多种方法(详解)
-
阻止事件冒泡和围绕.on()方法 [.selector]事件委托中冒泡情况的探讨
-
【Java】NIO中Selector的select方法源码分析
-
JQuery中$.each的使用方法 以及和$(selector).each()的区别
-
[PHP] 魔术方法__get __set __sleep __wakeup的实际使用
-
JQuery中$.each的使用方法 以及和$(selector).each()的区别
-
转载-再谈STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法总结