【问题标题】:How does a socket event get propagated/converted to epoll?套接字事件如何传播/转换为 epoll?
【发布时间】:2013-08-08 19:29:42
【问题描述】:

我很好奇 epoll_wait() 如何接收已注册的套接字(使用 epoll_ctl())准备好进行读/写的事件。

我相信 glibc 可以神奇地处理它。

那么,是否有文档描述如何为套接字触发以下事件?

  1. EPOLLPRI
  2. EPOLLRDNORM
  3. EPOLLRDBAND
  4. EPOLLWRNORM
  5. EPOLLWRBAND
  6. EPOLLMSG
  7. EPOLLERR
  8. EPOLLHUP
  9. EPOLLRDHUP

附:最初我试图将 sys/epoll.h 中的枚举 EPOLL_EVENTS 粘贴到我的盒子上; stackoverflow 认为我没有正确格式化代码块,尽管我用 pre 和 then 代码标签包装了它,知道吗?

【问题讨论】:

标签: c linux linux-kernel glibc centos6


【解决方案1】:

epoll 的所有关键工作都在内核中完成,用户空间 API 只是一个接口。 Why exactly does ePoll scale better than Poll? 上的上一个帖子涵盖了内核如何实现epoll 的详细信息。

至于描述事件及其触发方式的文档,epoll_ctl(2) man page 涵盖了每个事件,例如:

EPOLLIN
          The associated file is available for read(2) operations.

EPOLLOUT
          The associated file is available for write(2) operations.

要更好地描述EPOLLET,您需要阅读epoll(7) man page

这是complete example of how to use epoll

您使用epoll_ctl 请求您希望接收哪些事件EPOLLINEPOLLET,上面的代码是这样做的:

event.events = EPOLLIN | EPOLLET;
s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);

【讨论】:

  • 我的问题是还有许多其他可能的事件(正如我在原始问题中列出的那样)。但是,没有文档提到在什么情况下套接字上的每种类型的事件将传播到 epoll_wait()。举个例子,epoll_wait()会收到EPOLLRDNORM的socket怎么办?
  • 顺便说一句,虽然你的链接没有回答我的问题,但它确实有很多很好的信息。感谢分享 Shafik!
  • @Hei 我会澄清一下,您使用epoll_ctl 来请求您希望接收哪些事件,我将添加示例代码的链接。
  • 嗨,Shafik,我想你误解了我的问题。让我们坚持您刚刚添加的内容。假设我将 event.events 设置为 EPOLLIN | EPOLLET | EPOLLRD 标准。那么,我什么时候会收到 EPOLLRDNORM?我认为可能的答案是:1. 从不(那为什么?任何文件都这么说?)。 2. 当 x 发生时(那么任何文件都这么说?)。我的主要问题是在 epoll.h 中指定了许多事件,但我没有看到任何文档谈论我在原始问题中列出的一些事件。
  • @Hei 我有几个参考资料,我以为我链接的那个涵盖了所有这些,但是这个除了一个看起来像:turing.com.br/pydoc/2.7/library/select.html 让我看看我能不能找到一个更好的
【解决方案2】:

epoll 文档最明显的问题是它没有用“粗体大写”声明epoll 事件实际上与poll (2) 事件完全相同。事实上,在内核方面,epoll 会根据旧的 poll 事件名称来处理其事件:

#define POLLIN     0x0001  // EPOLLIN
#define POLLPRI    0x0002  // EPOLLPRI
#define POLLOUT    0x0004  // EPOLLOUT
#define POLLERR    0x0008  // EPOLLERR
#define POLLHUP    0x0010  // EPOLLHUP
#define POLLNVAL   0x0020  // unused in epoll
#define POLLRDNORM 0x0040  // EPOLLRDNORM
#define POLLRDBAND 0x0080  // EPOLLRDBAND
#define POLLWRNORM 0x0100  // EPOLLWRNORM
#define POLLWRBAND 0x0200  // EPOLLWRBAND
#define POLLMSG    0x0400  // EPOLLMSG
#define POLLREMOVE 0x1000  // unused in epoll
#define POLLRDHUP  0x2000  // EPOLLRDHUP

然后,对内核源代码的简要检查表明:

  • EPOLLINEPOLLRDNORM 相同(当数据可用于从文件描述符中读取时,epoll 返回 EPOLLIN | EPOLLRDNORM)。

  • EPOLLOUTEPOLLWRNORM 相同(当缓冲区空间可用于写入时,epoll 返回 EPOLLOUT | EPOLLWRNORM)。

  • EPOLLRDBANDEPOLLWRBAND 表示描述符上带外数据的可用性(在某些套接字上,这将是带有MSG_OOB 标志的数据发送到套接字)。

    李>
  • EPOLLPRI 是一个修饰符标志,总是增强一些其他事件(例如EPOLLERR)。它的使用取决于子系统,因为根据相关文件描述符的用途,它可能意味着不同的东西。

  • EPOLLMSG 似乎未被内核使用并且似乎没有任何用途。

  • EPOLLRDHUP 表示对等方已关闭其一侧的通道以供读取,但仍可能接收数据(便于确定没有更多请求数据进入)。

  • EPOLLHUP 表示对等方已关闭其一侧的通道。

【讨论】:

    猜你喜欢
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    相关资源
    最近更新 更多