<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## `ccnet`從單線程演變為多線程 ccnet現狀: * epoll * linux平臺 * 事件循環 * 單線程 * reactor * 監聽和新連接的事件都在主線程中 ## 單線程的`ccnet` ![rbx4XD.png](https://s3.ax1x.com/2020/12/29/rbx4XD.png) `ccnet`的單線程的角色: 1. `EventLoop`: 整個事件循環。 2. `EPollPoller`: 負責事件的收集。 3. `Channel`:負責事件的分發。 4. `Acceptor`:處理客戶端新連接,綁定監聽回調時間。 5. `TcpConnection`: 包含`EventLoop`組件,`Channel`組件,接收緩沖區和發送緩沖區,負責數據的收發。 6. `TcpServer`:包含`EventLoop`組件,`Acceptor`組件,客戶端連接`map`,還有回調接口 7. `Buffer`: 緩沖區 `ccnet`的單線程模型只是對epoll進行了封裝,然后根據reactor模型在代碼上進行了組件的區分,但是整體操作還是單線程,不能充分利用硬件資源。`TcpServer`的回調函數中,數據接收和業務處理在同一條線程中。 ## 單線程的`reactor` ![rbbTJS.png](https://s3.ax1x.com/2020/12/29/rbbTJS.png) Reactor模型中定義的三種角色: 1. Reactor:負責監聽和分配事件,將I/O事件分派給對應的Handler。新的事件包含連接建立就緒、讀就緒、寫就緒等。 2. Acceptor:處理客戶端新連接,并分派請求到處理器中。 3. Handler:將自身與事件綁定,執行非阻塞讀/寫任務。 單線程`reactor`的消息處理流程: 1. `Reactor`通過 `select/poll/epoll` 監控連接事件,通過`dispatch`進行分發 2. 如果是連接建立的事件,則由`acceptor`處理,并創建`handler`處理后續事件。 3. 如果不是建立連接事件,則`Reactor`會分發調用`Handler`來響應。 4. `handler`會完成`read`->業務處理->`send`的完整業務流程。 `Reactor`單線程模型只是在代碼上進行了組件的區分,但是整體操作還是單線程,不能充分利用硬件資源。`handler`業務處理部分沒有異步。 對于一些小容量應用場景,可以使用單`Reactor`單線程模型。但是對于高負載、大并發的應用場景卻不合適,主要原因如下: 1. 即便`Reactor`線程的CPU負荷達到100%,也無法滿足海量消息的編碼、解碼、讀取和發送。 2. 當`Reactor`線程負載過重之后,處理速度將變慢,這會導致大量客戶端連接超時,超時之后往往會進行重發,這更加重`Reactor`線程的負載,最終會導致大量消息積壓和處理超時,成為系統的性能瓶頸。 3. 一旦`Reactor`線程意外中斷或者進入死循環,會導致整個系統通信模塊不可用,不能接收和處理外部消息,造成節點故障。 于是所線程 ## 主從`Reactor`多線程模型 ![rbjKAI.png](https://s3.ax1x.com/2020/12/29/rbjKAI.png) 消息處理流程: 1. 從主線程池中隨機選擇一個`Reactor`線程作為`acceptor`線程,用于綁定監聽端口,接收客戶端連接 2. `acceptor`線程接收客戶端連接請求之后創建新的`SocketChannel`,將其注冊到主線程池的其它`Reactor`線程上。 3. 步驟2完成之后,業務層的鏈路正式建立,將`SocketChannel`從主線程池的Reactor線程的多路復用器上摘除,重新注冊到`SubReactor`線程池的線程上,并創建一個`Handler`用于處理各種**讀寫事件** 4. 當有新的事件發生時,`SubReactor`會調用連接對應的`Handler`進行響應 5. `Handler`通過`Read`讀取數據后,會分發給后面的`Worker`線程池進行業務處理 6. `Worker`線程池會分配獨立的線程完成真正的業務處理,如何將響應結果發給Handler進行處理 7. `Handler`收到響應結果后通過`Send`將響應結果返回給`Client` ## 多線程的`ccnet` ![rbzD8P.png](https://s3.ax1x.com/2020/12/29/rbzD8P.png) ![rbTFET.png](https://s3.ax1x.com/2020/12/29/rbTFET.png) 根據主從`Reactor`多線程模型,可以想到`ccnet`單線程模型中還缺少事件循環線程池`EventLoopThreadPool`組件和**worker線程池**,`EventLoopThreadPool`顧名思義,每個線程里都有一個事件循環。 可以把`ccnet`的單線程模型中 `TcpServer`組件修改一下,因為他包含事件循環`EventLoop`組件`和Acceptor`組件,也綁定了 `Acceptor`的新連接事件回調,`TcpServer`一個 `ccnet`多線程模型所需組件的集合,他還需要的組件如下: * `EventLoopThread`: on loop peer thread,負責開啟一個線程一個事件循環。 * `EventLoopThreadPool`: 是事件循環線程池。 * `TcpServer`: 增加`EventLoopThreadPool`組件。 修改`TcpServer.cc`的代碼: ``` void TcpServer::newConnection(int sockfd, const TcpAddr& peerAddr) { ... EventLoop *io_loop = thread_pool_->getNextLoop(); //增加的行 TcpConnectionPtr conn(new TcpConnection(io_loop, //修改的行 connName, sockfd, localaddr, peerAddr)); ... io_loop->runInLoop(std::bind(&TcpConnection::connectEstablished, conn));//修改的行 } ``` 修改`TcpServer.h`代碼: ``` class TcpServer { ... //thread pool std::shared_ptr<EventLoopThreadPool> thread_pool_; ... } ``` 修改example中的`EchoServer.cc`代碼: ``` server_.setNumThreads(4); //設置線程數量 ``` 詳細代碼請參考 github: https://github.com/diycat1024/ccnet
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看