• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            loop_in_codes

            低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

            Proactor和Reactor模式_繼續并發系統設計的掃盲

            6.6.2008

            Kevin Lynx

            Proactor和Reactor都是并發編程中的設計模式。在我看來,他們都是用于派發/分離IO操作事件的。這里所謂的
            IO事件也就是諸如read/write的IO操作。"派發/分離"就是將單獨的IO事件通知到上層模塊。兩個模式不同的地方
            在于,Proactor用于異步IO,而Reactor用于同步IO。

            摘抄一些關鍵的東西:

            "
            Two patterns that involve event demultiplexors are called Reactor and Proactor [1]. The Reactor patterns
            involve synchronous I/O, whereas the Proactor pattern involves asynchronous I/O.
            "

            關于兩個模式的大致模型,從以下文字基本可以明白:

            "
            An example will help you understand the difference between Reactor and Proactor. We will focus on the read
            operation here, as the write implementation is similar. Here's a read in Reactor:

            * An event handler declares interest in I/O events that indicate readiness for read on a particular socket ;
            * The event demultiplexor waits for events ;
            * An event comes in and wakes-up the demultiplexor, and the demultiplexor calls the appropriate handler;
            * The event handler performs the actual read operation, handles the data read, declares renewed interest in
              I/O events, and returns control to the dispatcher .

            By comparison, here is a read operation in Proactor (true async):

            * A handler initiates an asynchronous read operation (note: the OS must support asynchronous I/O). In this
              case, the handler does not care about I/O readiness events, but is instead registers interest in receiving
              completion events;
            * The event demultiplexor waits until the operation is completed ;
            * While the event demultiplexor waits, the OS executes the read operation in a parallel kernel thread, puts
              data into a user-defined buffer, and notifies the event demultiplexor that the read is complete ;
            * The event demultiplexor calls the appropriate handler;
            * The event handler handles the data from user defined buffer, starts a new asynchronous operation, and returns
              control to the event demultiplexor.

            "

            可以看出,兩個模式的相同點,都是對某個IO事件的事件通知(即告訴某個模塊,這個IO操作可以進行或已經完成)。在結構
            上,兩者也有相同點:demultiplexor負責提交IO操作(異步)、查詢設備是否可操作(同步),然后當條件滿足時,就回調handler。
            不同點在于,異步情況下(Proactor),當回調handler時,表示IO操作已經完成;同步情況下(Reactor),回調handler時,表示
            IO設備可以進行某個操作(can read or can write),handler這個時候開始提交操作。

            用select模型寫個簡單的reactor,大致為:

            ///
            class handler
            {
            public:
                
            virtual void onRead() = 0;
                
            virtual void onWrite() = 0;
                
            virtual void onAccept() = 0;
            }


            class dispatch
            {
            public:
                
            void poll()
                
            {
                    
            // add fd in the set.
                    
            //
                    
            // poll every fd
                    int c = select( 0&read_fd, &write_fd, 00 );
                    
            if( c > 0 )
                    
            {
                        
            for each fd in the read_fd_set
                        
            {    if fd can read
                                _handler
            ->onRead();
                            
            if fd can accept
                                _handler
            ->onAccept();
                        }
             

                        
            for each fd in the write_fd_set
                        
            {
                            
            if fd can write
                                _handler
            ->onWrite();
                        }

                    }

                }
             

                
            void setHandler( handler *_h )
                
            {
                    _handler 
            = _h;
                }
             

            private:
                handler 
            *_handler;
            }


            /// application
            class MyHandler : public handler
            {
            public:
                
            void onRead()
                
            {
                }
             

                
            void onWrite()
                
            {
                }
             

                
            void onAccept()
                
            {
                }

            }



            在網上找了份Proactor模式比較正式的文檔,其給出了一個總體的UML類圖,比較全面:

            proactor_uml

            根據這份圖我隨便寫了個例子代碼:

            class AsyIOProcessor
            {
            public:
                
            void do_read()
                
            {
                    
            //send read operation to OS
                    
            // read io finished.and dispatch notification
                    _proactor->dispatch_read();
                }
             

            private:
                Proactor 
            *_proactor;
            }


            class Proactor
            {
            public:
                
            void dispatch_read()
                
            {
                    _handlerMgr
            ->onRead();
                }
             

            private:
                HandlerManager 
            *_handlerMgr;
            }


            class HandlerManager
            {
            public:
                typedef std::list
            <Handler*> HandlerList; 

            public:
                
            void onRead()
                
            {
                    
            // notify all the handlers.
                    std::for_each( _handlers.begin(), _handlers.end(), onRead );
                }
             

            private:
                HandlerList 
            *_handlers;
            }


            class Handler
            {
            public:
                
            virtual void onRead() = 0;
            }


            // application level handler.
            class MyHandler : public Handler
            {
            public:
                
            void onRead() 
                
            {
                    
            // 
                }

            }



            Reactor通過某種變形,可以將其改裝為Proactor,在某些不支持異步IO的系統上,也可以隱藏底層的實現,利于編寫跨平臺
            代碼。我們只需要在dispatch(也就是demultiplexor)中封裝同步IO操作的代碼,在上層,用戶提交自己的緩沖區到這一層,
            這一層檢查到設備可操作時,不像原來立即回調handler,而是開始IO操作,然后將操作結果放到用戶緩沖區(讀),然后再
            回調handler。這樣,對于上層handler而言,就像是proactor一樣。詳細技法參見這篇文章。

            其實就設計模式而言,我個人覺得某個模式其實是沒有完全固定的結構的。不能說某個模式里就肯定會有某個類,類之間的
            關系就肯定是這樣。在實際寫程序過程中也很少去特別地實現某個模式,只能說模式會給你更多更好的架構方案。

            最近在看spserver的代碼,看到別人提各種并發系統中的模式,有點眼紅,于是才來掃掃盲。知道什么是leader follower模式,
            reactor, proactor,multiplexing,對于心中的那個網絡庫也越來越清晰。

            最近還干了些離譜的事,寫了傳說中的字節流編碼,用模板的方式實現,不但保持了擴展性,還少寫很多代碼;處于效率考慮,
            寫了個static array容器(其實就是template <typename _Tp, std::size_t size> class static_array { _Tp _con[size]),
            加了iterator,遵循STL標準,可以結合進STL的各個generic algorithm用,自我感覺不錯?;A模塊搭建完畢,解析了公司
            服務器網絡模塊的消息,我是不是真的打算用自己的網絡模塊重寫我的驗證服務器?在另一個給公司寫的工具里,因為實在厭惡
            越來越多的重復代碼,索性寫了幾個宏,還真的做到了代碼的自動生成:D。

            對優雅代碼的追求真的成了種癖好.  = =|

            posted on 2008-06-06 13:25 Kevin Lynx 閱讀(29581) 評論(7)  編輯 收藏 引用 所屬分類: network模塊架構

            評論

            # re: Proactor和Reactor模式_繼續并發系統設計的掃盲 2008-06-06 15:13 關中刀客

            模式是個好東西,但不是絕對的好東西,有時也不是很必要使用proactor  回復  更多評論   

            # re: Proactor和Reactor模式_繼續并發系統設計的掃盲 2008-06-06 15:40 Kevin Lynx

            @關中刀客
            傳說哥們和我同年同月差一天就同日生(我10號:d)

            還有,一直想看下你的cobra是個什么東西  回復  更多評論   

            # re: Proactor和Reactor模式_繼續并發系統設計的掃盲 2008-06-06 16:43 關中刀客

            To Kevin Lynx兄:
            呵呵,有緣有緣,我的cobra_win是一個網絡通訊庫,主要是針對iocp,采用異步多線程,底層目前已經有了自己的一套內存管理策略,比較完善的日志??欤〞r器模塊等等,感覺對于底層來說,已經相對的完善了,現在需要做的就是多多的改進和修正很多東西。呵呵,以后可以多多的交流~  回復  更多評論   

            # re: Proactor和Reactor模式_繼續并發系統設計的掃盲 2008-06-06 17:19 Kevin Lynx

            @關中刀客
            難道不開源?不知道能否分享下代碼。

            我之前在google,baidu都搜索過你這個東西,沒有發現類似googlecode之類的項目地址。。  回復  更多評論   

            # re: Proactor和Reactor模式_繼續并發系統設計的掃盲 2008-06-11 14:15 胡章優

            寫的很不錯
            這兩個模式在服務器開發中是應用的最多的算是

            另外一點開發的重點在集群管理上面

            刀客的東西可能想商業化,并沒有開源的打算  回復  更多評論   

            # re: Proactor和Reactor模式_繼續并發系統設計的掃盲[未登錄] 2008-06-12 19:25 楊粼波

            IOCP就是Proactor實現的系統級的事件分離器。

            leader follower模式,是一種并發模式,也可以說是一種策略。
            這些都可以在ACE的那兩本網絡編程的書里面看到講解。
            我最近一直看這書,一邊寫自己的網絡庫。之前寫的不滿意,現在重新寫一個。嘗試先用UML建模的方法。  回復  更多評論   

            # re: Proactor和Reactor模式_繼續并發系統設計的掃盲 2008-12-01 21:13 峰lntu

            proactor 很好用  回復  更多評論   

            久久亚洲日韩看片无码| 手机看片久久高清国产日韩| 久久亚洲精品成人AV| 久久精品人人槡人妻人人玩AV| 久久最新精品国产| 亚洲狠狠婷婷综合久久蜜芽| 97久久精品午夜一区二区| 亚洲精品午夜国产va久久| 国产精品一久久香蕉产线看| 久久精品一区二区影院| 亚洲精品无码久久久久去q | 久久国产精品一区| 亚洲精品tv久久久久久久久 | 亚洲精品蜜桃久久久久久| 国产精品99久久久久久www| 色欲久久久天天天综合网精品 | 91麻豆国产精品91久久久| 国产免费久久久久久无码| MM131亚洲国产美女久久| 久久久久av无码免费网| 久久久久亚洲AV成人网人人网站| 国产精品福利一区二区久久| 久久亚洲欧美国产精品| 亚洲va中文字幕无码久久| 香蕉久久影院| 2020国产成人久久精品| 无码任你躁久久久久久久| 日韩一区二区三区视频久久| 久久精品夜色噜噜亚洲A∨| 久久精品国产一区二区电影| 国产精自产拍久久久久久蜜| 久久免费精品视频| 国产成人精品久久二区二区 | 国产精品嫩草影院久久| 一本大道加勒比久久综合| 日本精品久久久久中文字幕| 久久精品国产99国产电影网 | 久久久中文字幕| 欧美麻豆久久久久久中文| 久久精品桃花综合| 中文字幕日本人妻久久久免费|