【发布时间】:2012-02-28 01:57:19
【问题描述】:
来自 epoll 的手册页:
epoll is a variant of poll(2) that can be used either as an edge-triggered
or a level-triggered interface
什么时候会使用边缘触发选项?手册页给出了一个使用它的示例,但我不明白为什么在示例中它是必要的。
【问题讨论】:
来自 epoll 的手册页:
epoll is a variant of poll(2) that can be used either as an edge-triggered
or a level-triggered interface
什么时候会使用边缘触发选项?手册页给出了一个使用它的示例,但我不明白为什么在示例中它是必要的。
【问题讨论】:
当 FD 准备好读取或写入时,您可能不一定要立即读取(或写入)所有数据。
只要 FD 准备就绪,电平触发的 epoll 就会一直唠叨你,而边缘触发的不会再打扰你,直到你下次收到 EAGAIN (所以它的代码更复杂,但可以效率更高,具体取决于您需要做什么)。
假设您正在从资源写入 FD。如果您将该 FD 准备好写入电平触发注册您的兴趣,您将收到持续通知,表明 FD 仍准备好写入。如果资源还不可用,那是在浪费唤醒,因为无论如何你不能再写了。
如果您将其添加为边沿触发,您会收到 FD 已准备好写入一次的通知,然后当其他资源准备好时,您会尽可能多地写入。然后如果write(2) 返回EAGAIN,你就停止写,等待下一个通知。
这同样适用于读取,因为您可能不想在准备好对它执行任何操作之前将所有数据拉入用户空间(因此必须对其进行缓冲等)。使用边缘触发的 epoll,您会在准备好读取时被告知,然后可以记住这一点并“随时”进行实际读取。
【讨论】:
read 失败并出现EAGAIN 但在调用epoll 之前数据可用?
epoll 如果 FD 已经准备好并且您尚未收到通知,则会立即返回。
在我的实验中,ET 不能保证只唤醒一个线程,尽管它通常只唤醒一个。 EPOLLONESHOT 标志就是为此目的。
【讨论】:
man 7 epoll:因为即使是边沿触发的epoll,在接收到多个数据块时也可以生成多个事件,调用者可以选择指定EPOLLONESHOT标志,告诉epoll 在收到带有epoll_wait(2) 的事件后禁用关联的文件描述符。当指定EPOLLONESHOT 标志时,调用者负责使用epoll_ctl(2) 和EPOLL_CTL_MOD 重新配置文件描述符。
EPOLLEXCLUSIVE 修复了多个 epoll FD 的雷鸣般的羊群问题。