linux手册翻译——epoll(7)

linux手册翻译——epoll(7),第1张

epoll — I/O 事件通知机制

epoll API与poll具有相同功能:监视多个文件描述符,以查看这些文件描述符中任何一个上可以进行特定的I/O *** 作,如是否可读/可写。epoll API可以使用edge-triggered和level-triggered两种接口,并且可以高性能的同时监视大量的fd,这是对epoll相对鱼poll的核心优势。

epoll的核心概念是epoll instance,这是一种内核数据结构,从用户空间角度看,可以视为一个包含两种列表的容器:

提供以下3个系统调用来创建和管理epoll instance:

两种触发模式:level_triggered (LT)和 edge_triggered(ET)

假设发生如下场景:

如果使用ET触发,那么步骤5就会阻塞挂起,这是因为对于ET模式而言,只有当缓冲区数据发生变化时才会触发事件(对于读,“变化”指新数据到达)。而对于LT而言,只要缓冲区中存在数据,就会一直触发。

使用ET时应使用非阻塞的fd (即无法读写时返回EAGIN,而非阻塞),以避免task阻塞导教其他fd无法监控。

合理使用ET模式步骤:

1)修改fd为非阻塞(non-blocking)

2)在read或write *** 作返回EAGIN后再执行wait等待事件。

为何ET需要非阻塞呢?因为ET模式下要循环多次read,并通过阻塞(即是否返回EAGIN)来确定数据是否全部读完。第一次执行read是不可能阻塞的。

若使用LT模式(默认情况下,使用ET模式),则可以将epoll看作是一个快速的poll,可以在任何地方使用epoll(LT)替换poll,因为他们的语义完全相同。

即使采用ET模式,在多线程的情况依然会导致产生多个事件(对于同一被监控的fd),这将导致多个线程 *** 作同一fd,可以使用EPOLLNESHOT标志避免,即在一次wait返回后禁止fd再产生事件,并在处理完成后使用epoll_ctl的MOD *** 作重新开启。

在多进程或多线程中,epoll_fd是共享的,这将导致所有线程都会知道事情的发生,但是epoll仅会唤醒一个线程,以规避“群惊”现象。

If the system is in autosleep mode via /sys/power/autosleep and an event happens which wakes the device from sleep, the device driver will keep the device awake only until that event is queued. To keep the device awake until the event has been processed, it is necessary to use the epoll_ctl(2) EPOLLWAKEUP flag.

When the EPOLLWAKEUP flag is set in the events field for a struct epoll_event, the system will be kept awake from the moment the event is queued, through the epoll_wait(2) call which returns the event until the subsequent epoll_wait(2) call. If the event should keep the system awake beyond that time, then a separate wake_lock should be taken before the second epoll_wait(2) call.

以下接口可用于限制 epoll 消耗的内核内存用量:

虽然 epoll 在用作级别触发接口时具有与 poll(2) 相同的语义,但边缘触发的用法需要更多说明以避免应用程序事件循环中的阻塞。

在下面例子中,listener 是一个非阻塞套接字,在它上面调用了 listen(2)。 函数 do_use_fd() 使用新的就绪文件描述符,直到 read(2) 或 write(2) 返回 EAGAIN。 事件驱动的状态机应用程序应该在收到 EAGAIN 后记录其当前状态,以便在下一次调用 do_use_fd() 时,它将继续从之前停止的位置read (2) 或write (2)。

当使用ET模式时,出于性能原因,可以通过EPOLL_CTL_ADD调用 epoll_ctl(2)指定 (EPOLLIN|EPOLLOUT)添加一次文件描述符。 避免使用 EPOLL_CTL_MOD 调用 epoll_ctl(2)在 EPOLLIN 和 EPOLLOUT 之间连续切换。

The epoll API is Linux-specific. Some other systems provide similar mechanisms, for example, FreeBSD has kqueue, and Solaris has /dev/poll.

通过 epoll 文件描述符监视的文件描述符集可以通过进程的 /proc/[pid]/fdinfo 目录中的 epoll 文件描述符条目查看。 有关更多详细信息,请参阅 proc(5)。

kcmp(2) KCMP_EPOLL_TFD *** 作可用于测试文件描述符是否存在于 epoll 实例中。

指Linux的版本。比如:

3.0版本[编辑]

托瓦兹宣布,大的变化是,“没有,绝对没有。132011年5月30日,托瓦兹宣布,“让我们确保我们真正的下一个版本不只是一个全新的闪亮的数字,而是有一个好的内核。”3.0的发布日接近Linux的20周年纪念日。

3.5版本[编辑]

·CoDel队列管理算法

seccomp filters

·沙盒机制

·Android风格的自动休眠和唤醒锁机制

·用户空间探测子系统uprobes TCP连接修复

减少重复确认加快转发的 TCP Early Retransmit

。连续性内存分配器

·kcmp()系统调用

·ext4文件系统加入元数据校验和

·改进Btrfs

3.6版本[编辑]

.客户端 TCP Fast Open实现

等等,更详细Linux知识可参考下《Linux就该这么学》。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/7128193.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-02
下一篇2023-04-02

发表评论

登录后才能评论

评论列表(0条)

    保存