I/O多路复用之epoll模型、触发模式

I/O多路复用之epoll模型

1 先谈谈select模型和poll模型的问题

  1. 由于select模型中,socket是由一个32个元素的int型数组中元素的二进制位存储的(位图存储),所以就有一个最大值的限定,在32位的系统中数量为32 * 4 * 8 = 1024;poll模型为了解决这个问题,使用了链表结构存储socket。
  2. 除了上述的问题,poll模型和select模型都存在以下两个很大程度上影响性能的问题:
  • 在调用select()函数或poll()函数之后,都要循环遍历所有socket查找需要处理的socket;
  • 在调用sele()函数或poll()函数之前,都需要传递所有监视对象的信息。
  1. 为了解决上述两个问题,我们需要重新构造一种I/O复用模型,这个模型必须满足两点:
  • 在监视范围发生变化时,只返回产生变化的对应socket;
  • 只传递以此监视对象。

2 epoll模型

epoll模型的出现是为了解决select和poll模型留下的缺陷,使用epoll模型搭建服务器涉及到以下三个函数,函数原型分别如下:

extern int epoll_create (int __size) __THROW;

extern int epoll_ctl (int __epfd, int __op, int __fd,
		      struct epoll_event *__event) __THROW;

extern int epoll_wait (int __epfd, struct epoll_event *__events,
		       int __maxevents, int __timeout);

1. epoll_create

参数:

  • __size:这个参数在早期的Linux版本中用来指定监听的文件描述符的数量上限,但在Linux 2.6.8及以后的版本中,这个参数被忽略,因为内核会根据需要动态地分配资源。不过,为了兼容性和代码可读性,通常还是会传递一个合理的值。

返回值:

  • 成功时返回一个新的文件描述符(epoll实例),用于后续的epoll_ctl和epoll_wait调用。
    失败时返回-1,并设置errno以指示错误。

使用方法:

  • 调用epoll_create创建一个epoll实例。
  • 使用返回的文件描述符作为epoll_ctl和epoll_wait的第一个参数。

2. epoll_ctl

参数:

  • __epfd:由epoll_create返回的文件描述符。
  • __op:要执行的操作,可以是以下三个值之一:
- EPOLL_CTL_ADD:添加一个新的文件描述符到epoll实例中。
- EPOLL_CTL_MOD:修改已存在的文件描述符的事件监听设置。
- EPOLL_CTL_DEL:从epoll实例中删除一个文件描述符。
  • __fd:要添加、修改或删除的文件描述符。
  • __event:指向一个epoll_event结构的指针,该结构指定了要监听的事件类型(如读就绪、写就绪等)和与该文件描述符关联的数据(通常用于区分不同的事件源)。

返回值:

  • 成功时返回0。
  • 失败时返回-1,并设置errno以指示错误。

使用方法:

  • 使用EPOLL_CTL_ADD将新的文件描述符添加到epoll实例中。
  • 使用EPOLL_CTL_MOD修改已存在的文件描述符的监听设置。
  • 使用EPOLL_CTL_DEL从epoll实例中删除文件描述符。

3. epoll_wait

参数:

  • __epfd:由epoll_create返回的文件描述符。
  • __events:指向一个epoll_event数组的指针,该数组用于存储从epoll实例中返回的事件。
  • __maxevents:__events数组的大小,即最多可以返回的事件数量。
  • __timeout:等待事件的超时时间(毫秒)。如果为-1,则表示无限等待,直到有事件发生。如果为0,则立即返回,不管是否有事件发生。

返回值:

  • 成功时返回发生的事件数量。
  • 如果超时且没有事件发生,则返回0。
  • 失败时返回-1,并设置errno以指示错误。

使用方法:

  • 调用epoll_wait等待事件的发生。
  • 如果有事件发生,epoll_wait会将事件信息填充到__events数组中,并返回发生的事件数量。
  • 遍历__events数组,处理每个事件。

3 epoll模型服务器实例

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<sys/epoll.h
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值