5

我一直认为 poll/epoll 不会阻塞。这就是 Nginx 等非阻塞服务器使用它们的原因。

但是在这个Stackoverflow 问题中,多次提到 poll 块。

那么 poll/epoll 会阻塞吗?

poll/epoll 与异步 IO 有何不同?

4

1 回答 1

10

是的,poll/epoll 块。为客户端提供服务的服务器通常无法像使用 epoll 这样的 I/O 事件通知模型的服务器那样扩展。poll 比 epoll (O(n) vs O(1)) 更老且效率更低。

[更新]

Nginx 不是非阻塞的。当一个请求进来时,epoll_wait 正在等待的事件之一被通知并且对 epoll_wait 的调用返回。然后 Nginx 循环通过为每个事件服务的信号事件。Nginx 源代码可在此处获得... http://nginx.org/download/nginx-1.1.1.tar.gz

看一下ngx_epoll_process_eventsnginx-1.1.1\src\event\modules\ngx_epoll_module.c中的函数

[更新2]

另请参阅 epoll_wait(2) 的手册页 ... http://linux.die.net/man/2/epoll_wait

#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

指定 -1 的超时使 epoll_wait(2) 无限期地等待,而指定等于 0 的超时使 epoll_wait(2) 立即返回,即使没有可用的事件(返回代码等于 0)。

[更新3]

为了向自己证明 Nginx / epoll 会阻塞,请在 Linux 上试试这个...

  1. 下载源代码并解压
  2. cd 到源目录
  3. ./configure --with-debug (注意:我必须添加 libpcre3-dev)
  4. make
  5. sudo make install
  6. 要启动 nginx:( /usr/local/nginx/sbin/nginx 注意:我必须先杀死 apache sudo /etc/init.d/apache2 stop
  7. sudo gdb
  8. file /usr/local/nginx/sbin/nginx
  9. b ngx_epoll_module.c:531 (设置断点)
  10. 在另一个终端窗口中,ps -ef | grep nginx并使用 nginx 工作进程(不是主进程)的 PI​​D
  11. 回到gdb,attach <PID of nginx worker>
  12. continue恢复进程

你可能需要continue几次,但它最终应该会阻塞。然后打开浏览器并转到http://localhost ...调试器应该在epoll_wait返回后立即中断。

于 2011-08-26T18:58:28.580 回答