EPOLL_WAIT(2) Linux Programmer's Manual EPOLL_WAIT(2)

本文详细介绍了epoll_wait与epoll_pwait这两个系统调用的功能及使用方法,包括它们如何等待I/O事件的发生,参数的意义,以及如何在多线程环境下安全地使用这些API。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NAME

epoll_wait, epoll_pwait - wait for an I/O event on an epoll file descriptor

SYNOPSIS

#include <sys/epoll.h>

int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,int maxevents, int timeout,const sigset_t *sigmask);

DESCRIPTION

  • epoll_wait() 等待在epfd描述符注册事件,events返回可操作的事件, maxevents 作为返回值返回,必须大于0,timeout 参数 指定阻塞的毫秒数,发生下面中的一个事件会返回:
    • 其中一个描述符交付一个事件
    • 调用被其他信号打断
    • 时间到达.
  • 注意timeout 会被折算成系统时间间隔(就是说并不准确), 指定-1将导致无限期阻塞, 指定0将不阻塞
       The struct epoll_event is defined as:

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

           struct epoll_event {
               uint32_t     events;    /* Epoll events */
               epoll_data_t data;      /* User data variable */
           };
  • 返回的每个结构体会包含跟用epoll_ctl()注册时相同事件
  • epoll_pwait()跟epoll_wait()和epoll_pwait()的关系就像select(2)和pselect(2):的关系 .epoll_pwait()允许应用安全的等待直到有事件被递交或被信号打断
  • The following epoll_pwait() call:
    ready = epoll_pwait(epfd, &events, maxevents, timeout, &sigmask);

is equivalent to atomically executing the following calls:

    sigset_t origmask;

    pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
    ready = epoll_wait(epfd, &events, maxevents, timeout);
    pthread_sigmask(SIG_SETMASK, &origmask, NULL);
  • sigmask可能被初始化位NULL, 这样的话就等价于epoll_pwait() 和epoll_wait().

  • 返回值:成功返回有事发生的描述符的个数或0,在等待期间如果发生错误,返回-1,并且errno被设置

  • 错误值

    • EBADF epfd不是一个有效的文件描述符
    • EFAULT 没有写权限
    • EINTR 调用被信号打断
    • EINVAL epfd不是一个epoll文件描述符,或maxevents小于等于0
  • NOTES

    • 当一个线程阻塞在epoll_pwait()调用时,另外一个线程在epfd增加一个文件描述符是可以的,如果新的文件描述符变为可读,将会导致 epoll_wait()不阻塞.
    • 关于在另一个线程取消一个描述符,这个线程会发生什么可以参考select(2).
  • BUGS

    • In kernels before 2.6.37, a timeout value larger than approximately
      LONG_MAX / HZ milliseconds is treated as -1 (i.e., infinity). Thus,
      for example, on a system where the sizeof(long) is 4 and the kernel HZ
      value is 1000, this means that timeouts greater than 35.79 minutes are
      treated as infinity.

    C library/kernel differences
    The raw epoll_pwait() system call has a sixth argument, size_t sigset‐
    size, which specifies the size in bytes of the sigmask argument. The
    glibc epoll_pwait() wrapper function specifies this argument as a fixed
    value (equal to sizeof(sigset_t)).

### SyS_epoll_wait 和 do_epoll_wait 的区别及用法 #### 函数定义与调用层次结构 `SyS_epoll_wait` 是系统调用接口函数,位于用户空间和内核之间的边界上。当应用程序通过 `epoll_wait()` 调用时,实际上是在调用这个系统调用入口点[^1]。 ```c SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout) { return do_epoll_wait(epfd, events, maxevents, timeout); } ``` `do_epoll_wait` 则是一个更底层的实现函数,在内核内部被多个地方调用。它负责处理实际的工作逻辑,包括等待事件的发生并返回给用户态程序[^2]。 #### 实现细节对比 - **参数传递** `SyS_epoll_wait` 接收来自用户的输入参数并通过验证后传入到 `do_epoll_wait` 中继续处理。这一步骤确保了安全性以及合法性检查[^3]。 - **上下文切换** 当进入 `SyS_epoll_wait` 后会触发一次从用户模式到核心模式的转换;而在完成工作之后再由 `do_epoll_wait` 返回结果前又会发生相反方向上的特权级变化[^4]。 - **错误处理机制** 如果在 `do_epoll_wait` 执行期间遇到任何异常情况,则会被捕获并将相应的错误码反馈回至 `SyS_epoll_wait`,最终呈现给应用层开发者作为诊断依据[^5]。 #### 使用场景说明 对于大多数开发人员来说,通常只需要关注如何正确地使用 `epoll_wait()` 进行高效的 I/O 多路复用操作即可,并不需要深入了解这两个具体函数的区别。然而理解它们之间关系有助于更好地掌握 Linux 内核工作机制及其性能优化原理[^6]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值