Epoll原理及实现

Epoll是Linux中提高多路IO并发监听效率的解决方案,对比select避免了数组拷贝和遍历的消耗。本文介绍了Epoll的创建、添加文件描述符的过程,并分析了其内部的数据结构关系。
摘要由CSDN通过智能技术生成

为什么会有Epoll?

  • 讲Epoll可能就不得不对早期的poll和select函数进行比较了。他们同属于多路IO并发监听,个人理解就是可以同时监听多个文件描述符的状态,如果有数据到来就返回对应的文件描述符,这样避免了读取一个文件描述符被阻塞,如果轮询又造成CPU浪费的情况
    同属于多路并非监听,select函数在监听到IO事件后,只是设置了标志位,返回了整个监听描述符的数组,在这种情况下,如果需要知道是哪个文件描述符有数据了,则需要遍历整个数组查看标志位,读完数据后,需要重新设置数组,然后再进行轮询操作,这种情况在文件描述符过多的情况下会造成cpu的数组拷贝(将整个数组拷贝到用户态,然后又拷贝到内核态)和遍历数组的消耗(遍历数组找到设置标志位的文件描述符),遍历复杂的为o(n),明显随着文件描述符的数量增加而变复杂
    为了解决这一消耗,便出现了epoll这个函数,epoll在添加完监听描述符后,不需要再次添加,同时在有IO事件时,也只返回有IO变化的描述符,这样提高了效率和并发的性能。

Epoll create

  • 对于epoll的创建,调用系统提供的系统函数即可:
/**
* @param size 废弃,但是不能小于0
* *
@returns 返回一个epoll句柄(即一个文件描述符)
*/
int epoll_create(int size);

系统函数调用值得注意的是,参数size不再是指定监听的文件描述符个数,它已经被忽视了,但是为了保持兼容,不能小于0。当然我们更关心的是内核态是怎么做的,在Linux源码目录fs/eventpoll.c文件中定义了对应的系统调用:

SYSCALL_DEFINE1(epoll_create, int, size)
{
	if (size <= 0)
		return -EINVAL;

	return do_epoll_create(0);
}

可以看到函数传递的size并没有被最终传递下去,但是如小于0则会被返回错误。继续往下看函数调用:

/*****************************************************************************
 Prototype    : do_epoll_create
 Description  : 创建epoll 文件描述符
 Input        : int flags  
 Output       : None
 Return Value : static
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2019/5/3
    Author       : 
    Modification : Created function

*****************************************************************************/
static int do_epoll_create(int flags)
{
	int error, fd;
	struct eventpoll *ep = NULL;
	struct file *file;

	if (flags & ~EPOLL_CLOEXEC)
		re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值