• <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 閱讀(29568) 評論(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 很好用  回復  更多評論   

            久久国产综合精品五月天| 国内精品久久久久久不卡影院| 久久精品国产福利国产秒| 成人妇女免费播放久久久| 97精品依人久久久大香线蕉97| 亚洲&#228;v永久无码精品天堂久久| 婷婷久久久亚洲欧洲日产国码AV| 欧美午夜A∨大片久久 | 日产精品久久久一区二区| 7777久久久国产精品消防器材| 久久综合鬼色88久久精品综合自在自线噜噜| 狠狠狠色丁香婷婷综合久久俺| 国产麻豆精品久久一二三| 99久久国产综合精品麻豆| 国产精品美女久久久免费| 思思久久99热只有频精品66| 狠狠色丁香久久婷婷综合图片| 亚洲国产精品无码久久一区二区| 国产婷婷成人久久Av免费高清| 国产一区二区三区久久精品| 伊人久久无码精品中文字幕| jizzjizz国产精品久久| 精品久久久久久无码不卡| 久久精品国产精品青草| 久久国语露脸国产精品电影| 亚洲国产二区三区久久| 久久国产精品成人影院| 久久AV高潮AV无码AV| 久久精品成人| 精品久久久久久无码中文字幕| 精品久久久噜噜噜久久久| 久久天天躁狠狠躁夜夜不卡| 精品乱码久久久久久夜夜嗨| 国产日韩久久久精品影院首页| 久久久精品人妻一区二区三区蜜桃 | 久久er99热精品一区二区| 久久久午夜精品| 久久99国内精品自在现线| 久久亚洲欧美国产精品| 日本福利片国产午夜久久| 99久久精品免费看国产|