程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> muduo庫源碼剖析(一) reactor模式

muduo庫源碼剖析(一) reactor模式

編輯:關於C++

一. Reactor模式簡介

Reactor釋義“反應堆”,是一種事件驅動機制。和普通函數調用的不同之處在於:應用程序不是主動的調用某個API完成處理,而是恰恰相反,Reactor逆置了事件處理流程,應用程序需要提供相應的接口並注冊到Reactor上,如果相應的時間發生,Reactor將主動調用應用程序注冊的接口,這些接口又稱為“回調函數”。

二. moduo庫Reactor模式的實現

muduo主要通過3個類來實現Reactor模式:EventLoop,Channel,Poller。

1. EventLoop

事件循環。moduo的線程模型為one loop per thread,即每個線程只能有一個EventLoop對象。EventLoop對象的生命周期通常和其所屬的線程一樣長。

數據成員:

const pid_t threadId_;保存當前EventLoop所屬線程id

boost::scoped_ptr poller_; 實現I/O復用 boost::scoped_ptr timerQueue_;

int wakeupFd_;

boost::scoped_ptr wakeupChannel_; 用於處理wakeupFd_上的可讀事件,將事件分發到handlRead() ChannelList activeChannels_; 有事件就緒的              Channel Channel* currentActiveChannel_;

MutexLock mutex_; pendingFunctors_回暴露給其他線程,所以需要加鎖 std::vectorpendingFunctors_;

主要功能函數:

loop(),在該函數中會循環執行以下過程:調用Poller::poll(),通過此調用獲得一個vector<channel*>activeChannels_的就緒事件集合,再遍歷該容器,執行每個Channel的Channel::handleEvent()完成相應就緒事件回調,最後執行pendingFunctors_排隊的函數。上述一次循環就是一次Reactor模式完成。

runInLoop(boost::function<void()>),實現用戶指定任務回調,若是EventLoop隸屬的線程調用EventLoop::runInLoop()則EventLoop馬上執行;若是其它線程調用則執行EventLoop::queueInLoop(boost::function<void()>將任務添加到隊列中(線程轉移)。EventLoop如何獲得有任務這一事實呢?通過eventfd可以實現線程間通信,具體做法是:其它線程向EventLoop::vector<boost::function<void()> >添加任務T,然後通過EventLoop::wakeup()向eventfd寫一個int,eventfd的回調函數EventLoop::handleRead()讀取這個int,從而相當於EventLoop被喚醒,此時loop中遍歷隊列執行堆積的任務。這裡采用Channel管理eventfd,Poller偵聽eventfd體現了eventfd可以統一事件源的優勢。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved