Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does poll/epoll block? How is it different from async IO?

I was always under the impression that poll/epoll doesn't block. That's why they are used by non-blocking servers such as Nginx.

But in this Stackoverflow question it was stated several times that poll blocks.

So does poll/epoll block?

And how is poll/epoll different from async IO?

like image 925
Continuation Avatar asked Aug 26 '11 18:08

Continuation


1 Answers

Yes, poll/epoll block. Servers that spin off threads to service clients typically don't scale as well as servers that use an I/O event notification model like epoll. poll is older and less efficient than epoll (O(n) vs O(1)).

[UPDATE]

Nginx is not non-blocking. When a request comes in, one of the events epoll_wait is waiting for is notified and the call to epoll_wait returns. Then Nginx loops through the signaled events servicing each one. The Nginx source code is available here ... http://nginx.org/download/nginx-1.1.1.tar.gz

Take a look at the ngx_epoll_process_events function in nginx-1.1.1\src\event\modules\ngx_epoll_module.c

[UPDATE2]

See also the man page for 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);

Specifying a timeout of -1 makes epoll_wait(2) wait indefinitely, while specifying a timeout equal to zero makes epoll_wait(2) to return immediately even if no events are available (return code equal to zero).

[UPDATE3]

To prove to yourself that Nginx / epoll blocks, try this on Linux...

  1. Download the source and unarchive
  2. cd to the source directory
  3. ./configure --with-debug (NOTE: I had to add libpcre3-dev)
  4. make
  5. sudo make install
  6. To start nginx: /usr/local/nginx/sbin/nginx (NOTE: I had to kill apache first sudo /etc/init.d/apache2 stop)
  7. sudo gdb
  8. file /usr/local/nginx/sbin/nginx
  9. b ngx_epoll_module.c:531 (to set a break point)
  10. In another terminal window, ps -ef | grep nginx and use the PID of the nginx worker process (not the master)
  11. back in gdb, attach <PID of nginx worker>
  12. continue to resume the process

You may have to continue a couple times but it should eventually block. Then open a browser and go to http://localhost ... the debugger should then break right after epoll_wait returns.

like image 151
dgnorton Avatar answered Sep 24 '22 15:09

dgnorton