epoll高度封装reactor,几乎所有可见服务器的底层框架

reactor是什么,如何理解? reactor所需组件流程分析 如何将epoll的IO驱动封装成reacto…

reactor是什么,如何理解?

reactor所需组件流程分析

如何将epoll的IO驱动封装成reactor事件反应堆驱动

reactor分块分析实现

注册事件处理器部分流程

多路复用器监视多路IO事件

事件分发器分发事件给对应的处理器

各种具体的事件处理器的分析

accept_cb : 新连接到来事件处理器

recv_cb : 处理读事件的处理器

send_cb 写事件处理器​

reactor整体代码以及测试结果

总结本章

  • 亲爱的各位友友们, 小杰从今天开始就自己网络服务器开发方向所学的东西,边学边写随笔,这个系列从epoll 封装 reactor 作为开始, 从0 到 1,小杰也是一样的从0 到 1,小杰之前学习网络高级IO的时候,学会了select poll 和 epoll 等支持IO多路复用的系统调用,但是都是处在很浅显的部分. 做过一部分练习,也是根据接口来封装出最简单的服务器,但是这些都没有借鉴过源码的精华
  • 所写的东西几乎都是根据自己的理解来写,但是小杰发现封装性不强,而且感觉写的东西很散,没有框架性,然后小杰为了想要走服务器开发方向,于是在网上找了一家机构进行系统的学习。 之后小杰会将所学尽数写成博文随笔,跟各位博友们相互分享讨论技术。 如果您看完小杰的博文觉得有所问题,请在评论区中给出您宝贵的意见,小杰会万分的感谢, 如果您觉得系列对自己有所帮助,麻烦关注下小杰,让我们共同学习进步
  • reactor是一种设计模式, 是服务器的重要模型, 框架: 是一种事件驱动的反应堆模式, 高效的事件处理模型
  • reactor 反应堆: 事件来了,执行,事件类型可能不尽相同,所以我们需要提前注册好不同的事件处理函数. 事件到来就由 epoll_wait 获取同时到来的多个事件,并且根据数据的不同类型将事件分发给事件处理机制 (事件处理器), 也就是我们提前注册的哪些接口函数
  • 思考reactor模型的设计思想和思维方式: 它需要的是事件驱动,相应的事件发生,我们需要根据事件自动的调用相应的函数,所以我们需要提前注册好处理函数的接口到reactor中, 函数是由reactor去调用的,而不是再主函数中直接进行调用的, 所以我需要使用回调函数. ——– 本质:函数指针
  • reactor中的 IO 使用的是select poll epoll 这种多路复用IO, 以便提高 IO 事件的处理能力,提高IO事件处理效率,支持更高的并发

Reactor 模式是处理并发 I/O 比较常见的一种模式,用于同步 I/O,中心思想是将所有要处理的 I/O 事件注册到一个 I/O 多路复用器上,同时主线程/进程阻塞在多路复用器上; 一旦有 I/O 事件到来或是准备就绪(文件描述符或 socket 可读、写),多路复用器返回并将事先注册的相应 I/O 事件分发到对应的处理器中。

组件

  • 多路复用器 :由操作系统提供,在 linux 上一般是 select, poll, epoll 等系统调用

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 事件分发器 :将多路复用器中返回的就绪事件分到对应的处理函数中,分发给事件处理器

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 事件处理器 :处理对应的IO事件

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

流程

  1. 注册事件 和 对应的事件处理器
  2. 多路复用器等待事件到来
  3. 事件到来,激发事件分发器分发事件到对应的处理器
  4. 事件处理器处理事件,然后注册新的事件, (比如处理读事件,处理完成之后需要将其设置为写事件再注册,因为读取之后我们需要针对业务需求进行数据处理,之后将其send 回去响应客户端结果,所以自然需要改成写事件,也就需要从新注册)
  • 其实现在流程还有运作方式已经清楚了,然后关键在于这个封装上了,IO事件fd应该如何封装,reactor又应该如何封装
  • 首先事件我们需要接口API, 为了后序可以使用reactor进行调用api函数, 然后 fd 肯定也是需要的,然后为了便于数据的临时存储我们需要用户态的recvbuffer 和 sendbuffer, 然后用户态的两个缓冲区中数据所占的大小我们也需要封装进去, why? 因为 我们 send 和 recv的时候都需要传入这两个参数. 于是这样一分析大体框架出来了

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 这个回调函数我们应该如何设置? 才能符合我们后序的需求?

首先我们肯定需要传入的是 fd 作为参数, 然后我们需要传入事件类型events 还有我们需要传入sockitem 结构体指针, 因为如果是读IO事件我们需要将从客户端读取的数据写入到sockitem的处在用户空间的recvbuffer中去, 以及如果是写IO事件我们需要将sockitem的处在用户空间的sendbuffer中的数据写回客户端

然后针对返回值我们设置为int类型即可, 所以接口设计为了如下结果,

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 然后就是针对reactor的封装了

首先我们肯定需要一个epoll句柄,所以epfd肯定需要封装进去,其次我们需要一个容器存储触发的IO事件,至此我们应该设置一个 sruct epoll_event events[512];在其中存储触发的IO事件,也就是将所有需要的全局数据封装成reactorwatermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 注册事件处理器部分流程

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 多路复用器监视多路IO事件

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 事件分发器分发事件给对应的处理器

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 各种具体的事件处理器的分析

accept_cb : 新连接到来事件处理器

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

recv_cb : 处理读事件的处理器

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

send_cb 写事件处理器watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 本章的核心是实现了一个网络经典模型,设计模式reactor 事件循环,事件驱动的反应堆模式.
  • 组件: 事件处理器 :回调函数callback 事件分发器 (将事件分发给对应的事件处理器), 多路复用器 (select poll epoll 等操作系统提供的多路复用技术)
  • 流程:
  1. 注册事件处理器,和书写事件处理函数
  2. 多路复用监视多路IO事件的来临
  3. 将触发的IO事件分发到对应的事件处理器中进行处理
本文来自网络,不代表软粉网立场,转载请注明出处:https://www.rfff.net/p/6336.html

作者: HUI

发表评论

您的电子邮箱地址不会被公开。

返回顶部