## ePump - an event-driven, multi-threaded c-framework
*A C-language framework based on I/O event notification, non-blocking communication and multi-threaded event-driven model helps you to develop servers with high-performance and numerous concurrent connections.*
*ePump是一个基于I/O事件通知、非阻塞通信、多路复用、多线程等机制开发的事件驱动模型的 C 语言应用开发框架,利用该框架可以很容易地开发出高性能、大并发连接的服务器程序。*
## 目录
* [一. ePump是什么?](#一-epump是什么)
* [二. ePump解决什么?](#二-epump解决什么)
* [三. ePump框架工作原理](#三-ePump框架工作原理)
* [3.1 ePump基础数据结构](#31-ePump基础数据结构)
* [3.1.1 设备(iodev_t)](#311-设备iodev_t)
* [3.1.2 定时器(iotimer_t)](#312-定时器iotime_rt)
* [3.1.3 事件(ioevent_t)](#313-事件ioevent_t)
* [3.2 ePump多线程架构](#32-epump多线程架构)
* [四. ePump框架工作模型](#四-epump框架工作模型)
* [4.1 快业务模型 -- 没有worker线程,只有ePump线程](#41-快业务模型----没有worker线程只有ePump线程)
* [4.2 复合业务模型 -- 少数ePump线程,大多数worker线程](#42-复合业务模型----少数ePump线程大多数worker线程)
* [五. ePump框架中的文件描述符FD](#五-epump框架中的文件描述符fd)
* [六. ePump框架的回调(Call Back)机制](#六-epump框架的回调call-back机制)
* [七. ePump框架的调度(Scheduling)机制](#七-epump框架的调度scheduling机制)
* [7.1 iodev_t设备绑定ePump线程](#71-iodev_t设备绑定epump线程)
* [7.1.1 Listen服务端口类的iodev_t设备](#711-listen服务端口类的iodev_t设备)
* [7.1.2 非Listen的iodev_t设备](#712-非Listen的iodev_t设备)
* [7.2 iotimer_t定时器](#72-iotimer_t定时器)
* [7.3 ioevent_t事件](#73-ioevent_t事件)
* [7.4 ePump线程](#74-epump线程)
* [7.5 worker工作线程](#75-worker工作线程)
* [八. ePump框架中惊群效应的处理机制](#八-epump框架中惊群效应的处理机制)
* [8.1 惊群效应(Thundering Herd Problem)](#81-惊群效应thundering-herd-problem)
* [8.2 惊群效应消耗什么?](#82-惊群效应消耗什么)
* [8.3 ePump框架中存在的惊群问题](#83-epump框架中存在的惊群问题)
* [8.3.1 worker线程组不存在惊群问题](#831-worker线程组不存在惊群问题)
* [8.3.2 ePump线程组的惊群问题](#832-epump线程组的惊群问题)
* [8.3.3 规避或弱化ePump框架惊群问题的措施](#833-规避或弱化epump框架惊群问题的措施)
* [九. How to build ePump](#九-how-to-build-epump)
* [十. How to integrate](#十-how-to-integrate)
* [十一. ePump框架相关的另外两个开源项目](#十一-epump框架相关的另外两个开源项目)
* [adif 项目](#adif-项目)
* [eJet Web服务器项目](#ejet-web服务器项目)
* [十二. 关于作者 老柯 (laoke)](#十二-关于作者-老柯-laoke)
***
一. ePump是什么?
------
ePump是一个基于I/O事件通知、非阻塞通信、多路复用、多线程等机制开发的事件驱动模型的 C 语言应用开发框架,利用该框架可以很容易地开发出高性能、大并发连接的服务器程序。
ePump是事件泵(Event Pump)的英文简称,顾名思义,意思是对各种网络读写事件、定时器事件等进行循环处理的泵,这些底层事件包括文件描述符FD的读就绪(Read Readiness)、写就绪(Write Readiness)、连接成功(Connected)、定时器超时(Timeout)等等。
ePump负责管理和监控处于非阻塞模式的文件描述符FD和定时器,根据其状态变化产生相应的事件,并派发到相应的工作线程或ePump线程的事件队列中,这些线程通过调用该事件关联的回调函数(Callback)来处理事件。
应用程序调用ePump框架提供的接口函数来预先创建、打开各种网络通信Socket文件描述符FD,或启动定时器等,并将其添加或绑定到ePump线程的监控队列中,对这些FD和定时器的状态监控是采用操作系统提供的I/O事件通知设施,如epoll、select、poll、kqueue、completion port等。
二. ePump解决什么?
------
许多服务器程序需要处理来自客户侧发起的大并发TCP连接请求、UDP请求,如Web服务器、Online服务器、消息系统等。早期实现的通信服务器类系统中,一个连接请求通常是由一个独立的进程或线程来接受并处理通信细节,如早先的Apache Web服务器;或者是利用OS提供的I/O异步事件通知、多路复用机制实现单进程下处理多个非阻塞并发连接请求,如SQUID系统。
这些系统采用的框架,要不在等待网络等I/O设备的数据到来之前阻塞自己,要不采用单进程多路复用模型,它们对CPU的利用效率多少存在一定的局限,而ePump框架是一种充分高效利用CPU处理能力的事件驱动模型框架。
ePump框架是一个多线程(未来增加多进程)事件驱动模型框架,基于文件描述符的异步就绪通知(Readiness Notification)机制,无需为等待"在路上"的数据而阻塞等待工作线程或工作进程。
该框架为每个文件描述符创建iodev_t对象,为定时驱动的应用程序创建定时器iotimer_t对象,利用操作系统提供的I/O事件通知设施如epoll、select等,将创建或打开的文件描述符FD设置为非阻塞模式,并添加到系统的监控管理列表中,对其状态变化进行异步回调通知。
对这两类对象的监控管理和事件通知派发是由ePump线程池来实现,对事件的回调处理是由Worker工作线程池或ePump线程池来完成。为了充分利用服务器硬件的性能,工作处理线程的个数一般跟CPU Core核数量一致。
大量复杂的底层处理细节都被封装成一些简单易用的API接口函数,通过这些API函数,开发者可以快速开发出支撑大并发的高性能服务器程序。
三. ePump框架工作原理
------
ePump框架是作者在其2003年开发的eProbe框架的基础上发展而来,是Event Pump的缩写,顾名思义这是一个事件驱动架构。
对于不同的I/O事件通知、非阻塞通信、多路复用机制,包括epoll、select、kqueue、completion port i/o等,其基本工作原理包括:
* 将FD增加到监听列表中
* 将FD从监听列表中删除
* 设置阻塞监听的时间
* 阻塞等待监听列表中FD set,等候R/W事件发生
* 轮询FD set列表检测各FD是否产生R/W事件,执行该事件对应的回调函数
* 检查Timeout,执行Timeout事件对应的回调函数
### 3.1 ePump基础数据结构
根据以上工作原理,我们设计ePump框架的几个基础数据结构:
#### 3.1.1 设备(iodev_t)
针对每个FD,用数据结构为iodev_t来管理,将文件描述符FD当作iodev_t设备,针对设备来管理读写状态、FD类型、要处理的读写事件、回调函数和回调参数、四元组地址等等. 我们把TCP监听socket、TCP连接socket(主动连接的、被动接收的)、UDP监听socket、UDP客户socket、Unix Socket、ICMP Raw Socket、UDP Raw Socket等等,都通过iodev_t设备来管理。
所有的iodev_t设备都会产生事件,ePump系统对iodev_t设备产生的事件进行处理,即通过事件驱动多线程来调用回调函数。
#### 3.1.2 定时器(iotimer_t)
类似iodev_t设备,能产生驱动事件的还有iotimer_t定时器, 设定一个时间并启动定时器后,系统将从当前时刻起到指定时间到达时,产生Timeout事件。
iotimer_t定时器有一次性的和周期性的,iotimer_t定时器数据结构管理定时器id、回调函数和回调参数、定时的时间等。
在Unix类OS系统,一个进程只能设置一个时钟定时器,由系统提供的接口来设置,常用的有alarm()和setitimer()。对于通信系统中大量存在各种定时器需求,同时考虑跨平台性等,系统提供的定时器接口一般都不能满足需求。我们在ePump系统中设计了iotimer_t数据结构,可提供毫秒级精度、同时大并发数量的定时器功能实现。
ePump架构中把定时器当做一个重要的基础设施,与文件描述符设备一样被ePump线程监听和管理。
#### 3.1.3 事件(ioevent_t)
ioevent_t事件是ePump的信使,管理事件类型、产生事件的对象、事件的回调函数和参数。
iodev_t设备基于各种硬件设备的R/W状态变动,触发ioevent_t事件的产生,而iotimer_t定时器根据设定的定时时间,当指定时间超时,就触发超时Timeout事件。
此外,应用程序可以注册用户钩子(Hook)事件,注册的用户钩子(Hook)事件需要绑定Callback回调函数和回调参数,最主要的是定义用户事件触发条件。
各种条件下产生的这些事件,都会被派送到工作线程的事件队列,驱动工作线程来进行事件处理,或者激活相应的回调函数来处理事件。
### 3.2 ePump多线程架构
ePump架构是由多线程来构成的,按照工作流程,这些线程分成两类,一类是ePump线程,另一类是worker线程。ePump线程职能主要是负责监听文件描述的R/W读写状态和定时器队列,创建读写事件和定时器事件,并将ioevent_t事件派发到各个worker线程的事件队列中。worker线程职能是监听事件队列,执行事件队列中各个事件关联的回调函数。
每个ePump线程采用I/O事件异步通知、非阻塞通信、多路复用等机制和模型,利用select/poll/epoll等系统调用,当被监听的文件描述符处于I/O读写就绪(I/O Readiness)时,ePump就会创建针对这些文件描述符的R/W读写事件,将这些R/W读写事件包装成ePump框架中标准的ioevent_t事件,并将其派发到各个worker工作线程的FIFO事件队列中。这些Event Queue FIFO事件队列是线程事件驱动模型的核心,每个ePump线程和每个worker线程都有一个这样的FIFO事件队列。此外,ePump线程还要维持并处理定时器队列,当定时器超时时,创建定时器超时ioevent_t事件,派发到相应的worker工作线程的事件队列中。
worker线程的主要职能就是阻塞等待该线程绑定的事件队列,当有事件到达时,通过唤醒机制,唤醒处于挂起状态的worker线程,被唤醒的工作线程将从其FIFO事件队列中,逐个地、循环地取走�
epump-master.zip
版权申诉
83 浏览量
2024-05-10
22:01:42
上传
评论
收藏 450KB ZIP 举报
灬Sunnnnn
- 粉丝: 3w+
- 资源: 97
最新资源
- Screenshot_2024-05-28-11-40-58-177_com.tencent.mm.jpg
- 基于Dart的Flutter小提琴调音器APP设计源码 - violinhelper
- 基于JavaScript和CSS的随寻订购网页设计源码 - web-order
- 基于MATLAB的声纹识别系统设计源码 - VoiceprintRecognition
- 基于Java的微服务插件集合设计源码 - wsy-plugins
- 基于Vue和微信小程序的监理日志系统设计源码 - supervisionLog
- 基于Java和LCN分布式事务框架的设计源码 - tx-lcn
- 基于Java和JavaScript的茶叶评级管理系统设计源码 - tea
- IMG_5680.JPG
- IMG_0437.jpg
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈