• <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

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

            Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲

            6.6.2008

            Kevin Lynx

            Proactor和Reactor都是并發(fā)編程中的設計模式。在我看來,他們都是用于派發(fā)/分離IO操作事件的。這里所謂的
            IO事件也就是諸如read/write的IO操作。"派發(fā)/分離"就是將單獨的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操作可以進行或已經(jīng)完成)。在結構
            上,兩者也有相同點:demultiplexor負責提交IO操作(異步)、查詢設備是否可操作(同步),然后當條件滿足時,就回調(diào)handler。
            不同點在于,異步情況下(Proactor),當回調(diào)handler時,表示IO操作已經(jīng)完成;同步情況下(Reactor),回調(diào)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()
                
            {
                }

            }



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

            proactor_uml

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

            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的系統(tǒng)上,也可以隱藏底層的實現(xiàn),利于編寫跨平臺
            代碼。我們只需要在dispatch(也就是demultiplexor)中封裝同步IO操作的代碼,在上層,用戶提交自己的緩沖區(qū)到這一層,
            這一層檢查到設備可操作時,不像原來立即回調(diào)handler,而是開始IO操作,然后將操作結果放到用戶緩沖區(qū)(讀),然后再
            回調(diào)handler。這樣,對于上層handler而言,就像是proactor一樣。詳細技法參見這篇文章。

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

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

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

            對優(yōu)雅代碼的追求真的成了種癖好.  = =|

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

            評論

            # re: Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲 2008-06-06 15:13 關中刀客

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

            # re: Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲 2008-06-06 15:40 Kevin Lynx

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

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

            # re: Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲 2008-06-06 16:43 關中刀客

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

            # re: Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲 2008-06-06 17:19 Kevin Lynx

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

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

            # re: Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲 2008-06-11 14:15 胡章優(yōu)

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

            另外一點開發(fā)的重點在集群管理上面

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

            # re: Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲[未登錄] 2008-06-12 19:25 楊粼波

            IOCP就是Proactor實現(xiàn)的系統(tǒng)級的事件分離器。

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

            # re: Proactor和Reactor模式_繼續(xù)并發(fā)系統(tǒng)設計的掃盲 2008-12-01 21:13 峰lntu

            proactor 很好用  回復  更多評論   

            亚洲综合久久夜AV | segui久久国产精品| 97视频久久久| 久久av无码专区亚洲av桃花岛| 亚洲色欲久久久综合网东京热| 久久久亚洲欧洲日产国码aⅴ| 久久成人国产精品二三区| 狠狠色丁香婷婷综合久久来来去 | 久久久久久免费一区二区三区| 精品国际久久久久999波多野| 亚洲一本综合久久| 无码国内精品久久人妻蜜桃 | 午夜精品久久久久久中宇| 久久人爽人人爽人人片AV| 久久国产香蕉视频| 色偷偷88888欧美精品久久久| 国产精品日韩欧美久久综合| 97精品依人久久久大香线蕉97| 成人精品一区二区久久久| 久久久精品国产免大香伊| 国产真实乱对白精彩久久| 久久狠狠高潮亚洲精品| 久久乐国产综合亚洲精品| 国产农村妇女毛片精品久久| 国产精品99久久久久久人| 久久精品中文字幕一区| 久久久无码精品午夜| 久久国产精品一区二区| 国产成人久久精品一区二区三区| 久久天天躁狠狠躁夜夜不卡| 久久久精品久久久久特色影视| 国产一级做a爰片久久毛片| 久久亚洲AV成人无码电影| 亚洲第一极品精品无码久久| 婷婷国产天堂久久综合五月| 久久久久这里只有精品| 久久免费国产精品一区二区| 久久精品国产精品亚洲精品| 国产成人精品久久免费动漫| 久久99国产精品久久久| 99久久国产免费福利|