libevent源码笔记(一) Reactor框架 - Go语言中文社区

libevent源码笔记(一) Reactor框架


最近读了部分libevent的源码,梳理并记录一下以加深自己的理解,也方便自己以及有需要的人后续查阅。

1. libevent 概述

在服务器编程中,I/O事件、信号和定时事件是服务器程序基本都要处理和考虑的三类事件。统一处理这三类事件能使代码逻辑清晰,简单易懂。比较常用的处理方法是利用I/O复用系统。但是在不同的系统有不同的I/O复用方式,如Solaris的dev/poll文件,FreeBSD、Mac的kqueue机制,Linux的epoll等。因此,对可能运行在不同系统的服务器程序来说,如何跨平台是个必须考虑的问题。此外,我们还需要考虑各执行实体如何协同处理客户连接、信号和定时器等,避免出现竞态条件。

Libevent就是开源社区提供的一个解决了上述问题的轻量级的I/O框架库,一些常用的开源软件如memcache,nodejs似乎都使用了libevent,类似的框架库还有ACE、ASIO等。

常用的框架库采用的模式有Reactor模式和Proactor模式。同步I/O模型通常用于实现Reactor模式,异步I/O模型通常用于实现Proactor模式。大多数I/O框架库都是以这两种模式中的一种或两种来实现的。Libevent采用的是Reactor模式。接下来先看一下什么是Reactor模式。

2. Reactor模式

Reactor模式通常要求主线程(对单线程来说可能是I/O处理单元)只负责监听文件描述符上是否有事件发生,有的话立即将该事件通知工作线程(对单线程来说是可能是逻辑单元)。除此之外,主线程(或I/O处理单元)不做其它任何实质性的工作。读写数据,接收新连接以及处理客户请求均在工作线程(或逻辑单元)中完成。一个epoll实现的Reactor模式的工作流程可能如下图2-1所示。

 

图2-1 Reactor工作流程

 

图2-1主要包括以下流程:

1) 主线程往epoll内核事件表中注册socket上的读事件

2) 主线程调用epoll_wait等待socket上有数据可读

3) socket有数据可读,epoll_wait通知主线程,主线程将socket可读事件放入请求队列。

4) 睡眠在请求队列上的某个工作线程被唤醒,从socket读取数据,处理请求,如果需要应答,注册该socekt的写就绪事件

5) 主线程调用epoll_wait等待socket可写

6) 当socket可写时,epoll_wait通知主线程。主线程将可写事件放入请求队列

7) 工作线程被唤醒,往socket上写入要返回给客户端的数据。


Reactor模式通常需要包括以下部分:事件循环框架Reactor,事件处理器EventHandler,句柄(也叫事件源)Handler,事件多路分发器EventDemultiplexer和具体的事件处理器ConcreteEventHandler。这些组件的关系如下图2-2所示。

 

图2-2 I/O框架库组件

接下来对每个组件做逐一说明:

a) 事件源或句柄(Handle)

在Linux上是指文件描述符或信号,在windows上是指Socket或者Handle。程序在指定的句柄上注册关心的事件,比如I/O读写事件,信号事件,超时事件等。

b) 事件处理器(EventHandle)和具体事件处理器(ConcreteEventHandle)

事件处理器通常是一个接口,有的实现包括handle_event回调函数,有的包括handle_input, handle_output, handle_timeout三个具体事件回调函数。用户需要根据自己的业务逻辑继承它来实现自己的具体事件处理器。事件处理器通常还应该包括一个获取句柄的方法,返回当前事件处理器关联的是哪个句柄。

c) 事件多路分发器(EventDemultiplexer)

当前Reactor使用的I/O多路复用机制,如select、epoll等。一般包括事件注册、移除和事件分发三个方法。分别用以向I/O复用注册,取消注册,以及调用select、poll、epoll_wait等等待函数。

d) Reactor反应器

事件管理的接口,内部调用EventDemultiplexer的注册注销接口进行注册、注销事件;运行事件循环。

综上,Reactor的一个运行时序图如下图2-3所示。

 

图2-3  Reactor模式工作时序图

 


注:本笔记基于libevent-2.0.21版本,阅读源码过程中一些不懂的地方参考了博客 http://blog.csdn.net/sparkliang/article/category/660506  和《Linux高性能服务器编程》一书


版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/thulpf/article/details/38473113
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-18 05:35:14
  • 阅读 ( 1255 )
  • 分类:Go Web框架

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢