epoll函数简介

原博客地址:https://www.cnblogs.com/lojunren/p/3856290.html

文件描述符的创建

#include <sys/epoll.h>
int epoll_create ( int size );

在epoll早期的实现中,对于监控文件描述符的组织并不是使用红黑树,而是hash表。这里的size实际上已经没有意义。

注册监控事件

#include <sys/epoll.h>
int epoll_ctl ( int epfd, int op, int fd, struct epoll_event *event );

函数说明:

  • fd:要操作的文件描述符
  • op:指定操作类型操作类型:
  • EPOLL_CTL_ADD:往事件表中注册fd上的事件
  • EPOLL_CTL_MOD:修改fd上的注册事件
  • EPOLL_CTL_DEL:删除fd上的注册事件
  • event:指定事件,它是epoll_event结构指针类型

epoll_event定义 :

struct epoll_event
{
    __unit32_t events;    // epoll事件
    epoll_data_t data;     // 用户数据 
};

结构体说明:

  • events:描述事件类型,和poll支持的事件类型基本相同(两个额外的事件:EPOLLET和EPOLLONESHOT,高效运作的关键)
  • epoll_data:存储用户数据
typedef union epoll_data
{
    void* ptr;              //指定与fd相关的用户数据 
    int fd;                 //指定事件所从属的目标文件描述符 
    uint32_t u32;
    uint64_t u64;
} epoll_data_t;

epoll_wait函数

类似于进程的wait()函数吧。

#include <sys/epoll.h>
int epoll_wait ( int epfd, struct epoll_event* events, int maxevents, int timeout );

函数说明:

  • 返回:成功时返回就绪的文件描述符的个数,失败时返回-1并设置errno
  • timeout:指定epoll的超时时间,单位是毫秒。当timeout为-1是,epoll_wait调用将永远阻塞,直到某个时间发生。当timeout为0时,epoll_wait调用将立即返回。
  • maxevents:指定最多监听多少个事件
  • events:检测到事件,将所有就绪的事件从内核事件表中复制到它的第二个参数events指向的数组中。

EPOLLONESHOT事件

使用场合:
一个线程在读取完某个socket上的数据后开始处理这些数据,而数据的处理过程中该socket又有新数据可读,此时另外一个线程被唤醒来读取这些新的数据。
于是,就出现了两个线程同时操作一个socket的局面。可以使用epoll的EPOLLONESHOT事件实现一个socket连接在任一时刻都被一个线程处理。
作用:
对于注册了EPOLLONESHOT事件的文件描述符,操作系统最多出发其上注册的一个可读,可写或异常事件,且只能触发一次。
使用:
注册了EPOLLONESHOT事件的socket一旦被某个线程处理完毕,该线程就应该立即重置这个socket上的EPOLLONESHOT事件,以确保这个socket下一次可读时,其EPOLLIN事件能被触发,进而让其他工作线程有机会继续处理这个sockt。
效果:
尽管一个socket在不同事件可能被不同的线程处理,但同一时刻肯定只有一个线程在为它服务,这就保证了连接的完整性,从而避免了很多可能的竞态条件。

### 回答1: `epoll` 函数是 Linux 系统中一个用于处理大量并发连接的 I/O 多路复用机制。它通过维护一个文件描述符集合来监测多个描述符的状态,以便在发生 I/O 事件时快速通知程序。 使用 `epoll` 的基本流程如下: 1. 创建 `epoll` 句柄:使用 `epoll_create` 或 `epoll_create1` 函数创建一个 `epoll` 句柄。 2. 注册文件描述符:使用 `epoll_ctl` 函数向 `epoll` 句柄中添加需要监测的文件描述符,并为每个文件描述符设置监测事件。 3. 进行等待:使用 `epoll_wait` 函数阻塞等待,直到有一个或多个文件描述符准备就绪。 4. 处理事件:当有文件描述符就绪时,处理相应的 I/O 事件。 5. 重复步骤 3 和 4,不断监测文件描述符的状态,处理 I/O 事件。 常见的使用方式是:创建一个线程,在线程中调用 `epoll_wait` 函数,当有文件描述符就绪时通过回调函数处理相应的 I/O 事件。 ### 回答2: epoll函数是Linux系统中一种高效的I/O事件通知机制,用于管理大量的文件描述符。其使用方式如下: 1. 创建一个epoll句柄: int epoll_create(int size); 创建一个epoll实例,并返回一个文件描述符,size表示期望监听的文件描述符数量,通常可以设置为任意正整数。 2. 注册文件描述符和事件: int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); epfd为epoll实例的文件描述符,op为操作类型(EPOLL_CTL_ADD表示添加,EPOLL_CTL_MOD表示修改,EPOLL_CTL_DEL表示删除),fd为需要监听的文件描述符,event为事件类型结构体指针。 3. 开始监听文件描述符事件: int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); epfd为epoll实例的文件描述符,events为存储事件的数组,maxevents表示最大监听的事件数量,timeout表示等待时间(-1表示一直等待,0表示立即返回,>0表示超时时间)。 4. 对返回的事件进行处理: 在epoll_wait函数返回后,可以遍历events数组,根据每个事件的文件描述符和事件类型进行处理。 5. 关闭epoll实例: close(epfd); 使用完epoll实例后,需要调用close函数关闭,释放相关资源。 以上就是epoll函数的基本使用流程。通过epoll可以高效地监听大量的文件描述符事件,减少系统资源的消耗。在实际开发中,可以根据需要设置不同的事件类型和回调函数,实现具体的业务逻辑。 ### 回答3: epoll函数是Linux中用于处理I/O事件的一种高效机制。它可以监视一组文件描述符,并在其中的任意一个文件描述符上发生事件时进行相应的处理。 使用epoll函数的基本步骤如下: 1. 调用epoll_create函数创建一个epoll的句柄,该句柄被用于后续的相关操作。 2. 使用epoll_ctl函数epoll句柄中注册需要监视的文件描述符和事件。通过该函数可以实现添加、修改和删除文件描述符以及相应事件的功能。 3. 使用epoll_wait函数等待事件的发生。epoll_wait会一直阻塞,直到有文件描述符上的事件发生。一旦有事件发生,epoll_wait会返回所发生事件的文件描述符和相应的事件类型。 4. 根据返回的事件类型,进行相应的处理。 epoll函数有三个基本的系统调用: 1. epoll_create函数用来创建一个epoll实例,返回一个epoll句柄。 2. epoll_ctl函数用于操作epoll实例,可以实现添加、修改和删除文件描述符以及相应事件的功能。 3. epoll_wait函数用于等待事件的发生,一旦事件发生则返回相应的文件描述符和事件类型。 epoll函数的使用优点包括: - 支持大量的连接,可以监视数万个文件描述符。 - 存储监视文件描述符的数据结构(epoll实例)可以重复利用,避免了每次都需要重新设置的问题。 - 使用epoll_wait函数进行等待事件的发生,避免了轮询的方式,提高了效率。 总之,epoll函数是Linux中用于处理I/O事件的一种高效机制,可以通过创建、操作epoll实例和等待事件的发生来实现对文件描述符的监视和相应事件的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值