《UNP》随笔——epoll的理解及应用

本文详细介绍了Linux环境下,为什么从select和poll转向使用epoll的原因,主要对比了epoll与select在性能上的差异。文章还详细讲解了epoll的三个核心函数:epoll_create、epoll_ctl和epoll_wait的使用方法,强调了epoll的优势在于避免了每次调用时传递监视对象信息。最后,提到了epoll的条件触发和边缘触发两种模式。
摘要由CSDN通过智能技术生成

1. 为什么要使用epoll?

实现I/O复用的传统方法有select和poll,但这两者都无法实现同时接入上百个客户端,所以select并不适合当前以Web服务端开发为主流的现代开发环境,于是就产生了epoll。epoll是linux平台所支持的,在Windows平台对应支持的是IOCP。

1.1 基于select的I/O复用技术速度慢的原因

  • 调用select函数后,需要对所有文件描述符执行循环检查语句。
  • 每次调用select函数时都需要向该函数传递监视对象信息。

循环语句不是最大的麻烦,每次传递监视对象信息到操作系统中才是最大的麻烦。
应用程序向操作系统传递数据将对程序造成很大负担,而且无法通过优化代码解决,因此将成为性能上的致命弱点。
select函数与文件描述符有关,更准确地说,是监视套接字变化的函数。而套接字是由操作系统管理的,所以select函数绝对需要借助于操作系统才能完成功能。select函数的这一缺点可以通过如下方式弥补:

"仅向操作系统传递1 次监视对象,监视范围或内容发生变化时只通知发生变化的事项。”

这样就无需每次调用select函数时都向操作系统传递监视对象信息,但前提是操作系统支持这种处理方式(每种操作系统支持的程度和方式存在差异)。Linux的支待方式是epoll, Windows的支持方式是IOCP 。

select 的优点
epoll方式只在Linux下提供支持,也就是说,改进的I/O复用模型不具有兼容性。相反,大部分操作系统都支持select函数。只要满足或要求如下两个条件, 即使在Linux平台也不应拘泥于epoll 。

  • 服务器端接入者少。
  • 程序应具有兼容性。

2. epoll函数的介绍

epoll函数具有如下优点,这些优点正好与之前的select函数缺点相反。

  • 无需编写以监视状态变化为目的的针对所有文件描述符的循环语句。
  • 调用对应于select函数的epoll_wait函数时无需每次传递监视对象信息。

epoll服务器端实现中需要的3个函数,

  • epoll_ create: 创建保存epoll文件描述符的空间。
  • epoll_ctl: 向空间注册并注销文件描述符。
  • epoll_wait: 与select函数类似,等待文件描述符发生变化。

select和epoll的不同

select方式

  • 用fd_set变量保存监视对象文件描述符。
  • 用FD_SET,FD_CLR添加和删除对象。
  • select函数等待文件描述符的变化。
  • 通过FD_ISSET查看状态变化的文件描述符。

epoll方式

  • 操作系统负责保存监视对象文件描述符,因此需要向操作系统请求创建保存文件描述符的空间。
  • 通过epoll_ctl 函数请求操作系统添加和删除对象。
  • epoll_wait函数等待文件描述符的变化。
  • 通过结构体epoll_event将发生变化的文件描述符单独集中到一起。

epoll_event结构体:

struct epoll_event
{
   
	uint32_t events;
	epoll_data_t data;
}
 
typedef union epoll_data
{
   
	void *   ptr;
	int      fd;
	uint32_t u32;
	uint64_t u64;
} epoll_data_t;

声明足够大的epoll_even结构体数组后,传递给epoll_wait函数时.发生变化的文件描述符信息将被填入该数组。因此, 无需像select函数那样针对所有文件描述符进行循环。

2.1 epoll_create

#include <sys/epoll. h>
int epoll_create(int size);
/*
成功时返回epoll 文件描述符,失败时返回-1。
#size: epoll实例的大小。
*/

调用epoll_creat函数创建的文件描述符保存空间称为“epoll例程”,有些情况下名称会不同。通过传递size参数来决定空间大小,但这个值只是给操作系统一个建议,换言之,size并不能决定epoll的大小。

Linux 2.6.8 之后的内核将完全忽略传入epoll_create 函数的size 参数,因为内核会根据情况调整epoll 例程的大小。

epoll_creat函数创建的资源与套接字相同,也由操作系统管理。因此,此函数和创建套接字的情况相同,也会返回文件描述符。需要终止时,与其他文件描述符相同,也要调用close函数。

2.2 epoll_ctl

生成例程后,应在其内部注册监视对象文件描述符,此时使用epoll_ctl函数。

#include <sys/epoll. h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event * event);
//成功时返回0 , 失败时返回-1 。
#epfd   用千注册监视对象的epoll例程的文件描述符。
#op     用千指定监视对象的添加、删除或更改等操作。
#fd     需要注册的监视对象文件描述符。
#event  监视对象的事件类型。

该函数看起来复杂,但是调用语句就很容易理解,假设按如下形式调用epoll_ctl函数:

epoll_ctl(A, EPOLL_CTL_ADD, B, C);

第二个参数 EPOLL_CTL_A

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值