莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          再談Selector的wakeup方法

          Posted on 2009-02-01 11:15 dennis 閱讀(3377) 評論(0)  編輯  收藏 所屬分類: javalinux & C
              過去推薦過兩篇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上篇的新回復中已經有人提到。
          主站蜘蛛池模板: 子洲县| 田阳县| 淮北市| 阿瓦提县| 梨树县| 满洲里市| 新巴尔虎右旗| 沁阳市| 阿拉善右旗| 伊宁市| 响水县| 淅川县| 桐柏县| 浦城县| 赤壁市| 衡南县| 天台县| 连云港市| 舒城县| 休宁县| 杭锦旗| 托里县| 花垣县| 莲花县| 拜城县| 沂南县| 海林市| 宜州市| 涿州市| 象州县| 井陉县| 茂名市| 永清县| 柳江县| 江源县| 莱西市| 襄城县| 宁陵县| 钟祥市| 丁青县| 桃园市|