日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络编程模型 / Reactor

發布時間:2024/10/14 编程问答 121 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络编程模型 / Reactor 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前一直不理解 Reactor 模型的含義,后來在知乎上看見了一個 demo,再結合文字終于理解什么是 Reactor 模型了,這里分享給大家。

一、介紹

網絡編程模型通常有如下幾種:ReactorProactorAsynchronous Completion Token and Acceptor-Connector。本文主要對最主流的 Reactor模型進行介紹。

通常網絡編程模型處理的主要流程如下

initiate => receive => demultiplex => dispatch => process events

I/O 多路復用可以用作并發事件驅動(event-driven)程序的基礎,即整個事件驅動模型是一個狀態機,包含了狀態(state), 輸入事件(input-event), 狀態轉移(transition), 狀態轉移即狀態到輸入事件的一組映射。通過 I/O 多路復用的技術檢測事件的發生,并根據具體的事件(通常為讀寫),進行不同的操作,即狀態轉移。

Reactor 模式是一種典型的事件驅動的編程模型,Reactor 逆置了程序處理的流程,其基本的思想即為 Hollywood Principle — 'Don't call us, we'll call you'。

普通的函數處理機制為:調用某函數 -> 函數執行, 主程序等待阻塞 -> 函數將結果返回給主程序 -> 主程序繼續執行。

Reactor 事件處理機制為:主程序將事件以及對應事件處理的方法在 Reactor 上進行注冊,如果相應的事件發生,Reactor 將會主動調用事件注冊的接口,即 回調函數。libevent 封裝了 epoll 并注冊相應的事件(I/O讀寫,時間事件,信號事件)以及回調函數,實現的事件驅動的框架。

二、架構

1、事件(事件源)

linux 上為文件描述符,handler 即為注冊在特定事件上的程序,事件發生通常在 linux 下為 I/O 事件,由操作系統觸發。

2、Reactor (反應器)

事件管理的接口,內部使用 event demultiplexer 注冊、注銷事件;并運行事件循環,當有事件進入"就緒"狀態時,調用注冊事件的回調函數處理事件。

class Reactor { public:int register_handler(EventHandler *pHandler, int event);int remove_handler(EventHandler *pHandler, int event);void handle_events(timeval *ptv); }

3、Event demultiplexer(事件多路分發機制)

通常是由操作系統提供的 I/O 多路復用的機制,例如 select,epoll。程序首先將 handler(事件源)以及對應的事件注冊到 event demultiplexer 上;當有事件到達時,event demultiplexer 就會發出通知,通知 Reactor 調用事件處理程序進行處理。

4、Event Handler(事件處理程序)

事件處理程序提供了一組接口,在 Reactor 相應的事件發生時調用,執行相應的事件處理,通常會綁定一個有效的 handler 。

class Event_Handler { public:// events maybe read/write/timeout/close .etcvirtual void handle_events(int events) = 0;virtual HANDLE get_handle() = 0; }

三、實現

#include <sys/epoll.h> #include <unistd.h> #include <iostream> #include <array> #include <unordered_map>typedef std::string EventType; class MyEventDemultiplexer { public:static const int NO_FLAGS = 0;static const int BLOCK_INDEFINITELY = -1;static const int MAX_EVENTS = 5;MyEventDemultiplexer(){fileDescriptor = epoll_create1(NO_FLAGS);event.data.fd = STDIN_FILENO;//設置epoll event 為 EPOLLIN (對應文件描述符可讀), EPOLLPRI (對應文件描述符有緊急事件可讀)event.events = EPOLLIN | EPOLLPRI;}~MyEventDemultiplexer(){close(fileDescriptor);}int wait(){return epoll_wait(fileDescriptor, events.data(), MAX_EVENTS, BLOCK_INDEFINITELY);}int control(){return epoll_ctl(fileDescriptor, EPOLL_CTL_ADD, STDIN_FILENO, &event);}private:int fileDescriptor;struct epoll_event event;std::array<epoll_event, MAX_EVENTS> events{}; };class MyEventHandler { public:int handle_event(EventType et){std::cout << "Event Handler: " << et << std::endl;return 0;} };class Reactor { public:Reactor(){m_event_demultiplexer.control();}void addHandler(std::string event, MyEventHandler callback){handlers.emplace(std::move(event), std::move(callback));}void run(){while (true){int numberOfEvents = wait();for (int i = 0; i < numberOfEvents; ++i){std::string input;std::getline(std::cin, input);try{// 根據的具體的事件去找對應的handler,并執行相應的操作handlers.at(input).handle_event(EventType(input));}catch (const std::out_of_range &e){std::cout << "no handler for " << input << std::endl;}}}}private:std::unordered_map<std::string, MyEventHandler> handlers{};MyEventDemultiplexer m_event_demultiplexer;int wait(){int numberOfEvents = m_event_demultiplexer.wait();return numberOfEvents;} };int main() {Reactor reactor;reactor.addHandler("a", MyEventHandler{});reactor.addHandler("b", MyEventHandler{});reactor.run(); }

結果:

a Event Handler: a b Event Handler: b c no handler for c

轉載于:https://zhuanlan.zhihu.com/p/93612337

(SAW:Game Over!)

?

總結

以上是生活随笔為你收集整理的网络编程模型 / Reactor的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。