5

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?

Community
  • 1
  • 1
Continuation
  • 12,722
  • 20
  • 82
  • 106
  • select/poll/epoll blocks. However, it can be used to wait for *multiple* events at once, not just a single event. – Joey Adams Nov 15 '11 at 16:29

1 Answers1

10

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.

dgnorton
  • 2,237
  • 16
  • 12
  • 1
    If epoll blocks, how does servers that use epoll (eg. Nginx) become non-blocking? – Continuation Aug 26 '11 at 19:11
  • Thanks for the updates. So if Nginx is blocking, how is it different from a server like Apache that also blocks? Also the man page for epoll (http://linux.die.net/man/4/epoll) talks about non-blocking usage: "The epoll interface, when used with the EPOLLET flag ( Edge Triggered ) should use non-blocking file descriptors to avoid having a blocking read or write starve the task that is handling multiple file descriptors." What am I missing? – Continuation Aug 26 '11 at 21:00
  • 2
    Continuation: epoll_wait() itself is a blocking interface. Whenever you call epoll_wait(), it blocks your thread/process until any of the monitored events happens on the registered descriptors. The man page talks about epoll's usage for non-blocking FDs, which is what epoll monitors, not the epoll itself. In other words, it says that you should register only non-blocking FDs on epoll if you are using EPOLLET. Anyhow, either you ask epoll to monitor a non-blocking or blocking FD, epoll interface, itself, is still blocking-based – ddoman Nov 06 '11 at 23:17
  • 2
    You may use epoll_wait() like a non-blocking interface by giving the timeout value as 0. – ddoman Nov 06 '11 at 23:44
  • @Continuation Apache will handle the connection with a new process/thread, which will block. For example, 1000 threads that are blocked waiting for a response. In comparison, Nginx would use epoll to register 1000 connections. However if there is nothing to do with these 1000 connections, it will block. When an event occurs, it will proceed. However to do this, you only need one thread, not a thousand. – Heuriskos Dec 09 '19 at 14:08