套接字事件如何传播/转换为epoll?

时间:2013-08-07 12:13:59

标签: c linux linux-kernel glibc centos6

我很好奇epoll_wait()如何接收已注册的套接字(带有epoll_ctl())可以读/写的事件。

我相信glibc会神奇地处理它。

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

  1. EPOLLPRI
  2. EPOLLRDNORM
  3. EPOLLRDBAND
  4. EPOLLWRNORM
  5. EPOLLWRBAND
  6. EPOLLMSG
  7. EPOLLERR
  8. EPOLLHUP
  9. EPOLLRDHUP
  10. P.S。最初我试图将enum EPOLL_EVENTS粘贴到我的盒子上的sys / epoll.h中; stackoverflow认为我没有正确格式化代码块,虽然我用pre和then代码标签包装它,任何想法?

2 个答案:

答案 0 :(得分:6)

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表示描述符上带外数据的可用性(在某些套接字上,这将是传递给socket的MSG_OOB标志的数据发送)。

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

  • EPOLLMSG似乎未被内核使用,似乎没有用处。

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

  • EPOLLHUP表示同伴关闭了频道的一面。

答案 1 :(得分: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);