epoll 如何知道内核中的 socket 已经准备好?

How does epoll know socket is ready in kernel?

我在 epool 源代码中没有找到任何关于 epoll 如何知道套接字已准备好用于 read/write 的提示。

  1. epoll是否在内核中注册了一个callback
  2. epool是否在内核中为read/write注册了一个signal
  3. 还是别的?

非常感谢。

简答

不仅用于 epoll,而且通常用于 "blocking I/O"(例如,read() 系统调用使用相同的机制),内核使用 waitqueues(不不要将它们与 workqueues 混淆,这是完全不同的机制)。如果您检查 ep_poll() 实施,它甚至会记录在评论中。

一些不太有趣的细节

为了让当前线程在等待队列中休眠,通常会使用 wait_event_interruptible() 调用。然而,epoll_wait 不会那样做。相反,它通过使用 __add_wait_queue_exclusive() 将自己添加到等待队列,使用 set_current_state(TASK_INTERRUPTIBLE) 使自己进入睡眠状态并检查在循环中被唤醒的原因,从而重新实现此调用将执行的操作。最终结果是相同的——当前线程将进入可中断睡眠状态,可以通过发送信号终止(在这种情况下 epoll_wait 将 return EINTR)或被唤醒ep_poll_callback 通过 waitqueues 机制。