You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If both fields of the
timeval structure are zero, then select() returns immediately. (This
is useful for polling.) If timeout is NULL (no timeout), select()
can block indefinitely.
[《Linux/UNIX系统编程手册》Michael Kerrisk著 P1094]
Poll:
关于Poll是否阻塞:
在使用int poll(struct pollfd *fds, nfds_t nfds, int timeout)函数获取信息时,可以通过指定timeout的值来决定是否阻塞[6](当timeout<0时,会无限期阻塞;当timeout=0时,会立即返回)。
Specifying a negative value
in timeout means an infinite timeout. Specifying a timeout of zero
causes poll() to return immediately, even if no file descriptors are
ready.
[《Linux/UNIX系统编程手册》Michael Kerrisk著 P1099]
Epoll:
关于Epoll是否阻塞:
在使用epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)函数来获取是否有发生变化/事件的文件描述符时,可以通过指定timeout来指定该调用是否阻塞(当timeout=-1时,会无限期阻塞;当timeout=0时,会立即返回)。[1]
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).
[《Linux/UNIX系统编程手册》Michael Kerrisk著 P1116]
关于Epoll是否同步:
当前是否有发生变化/事件的文件描述符需要通过epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)显式地进行查询,因此不是异步;其他资料佐证了这一点[2]。
Activity
CyC2018 commentedon Apr 13, 2018
@LeroChen 我明天再认真查阅一下相关资料,如果您有比较详细的资料的话,麻烦分享一下。
NutshellySima commentedon Apr 15, 2018
@CyC2018
(参考资料见最后,已用方括号标出)
总的讨论
所有I/O多路复用操作都是同步的,涵盖
select/poll
。[2][4]阻塞/非阻塞是相对于同步I/O来说的,与异步I/O无关。
select/poll/epoll
本身是同步的,可以阻塞也可以不阻塞。Select:
关于Select是否阻塞:
在使用
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
函数时,可以设置timeval
决定该系统调用是否阻塞[5]。[《Linux/UNIX系统编程手册》Michael Kerrisk著 P1094]

Poll:
关于Poll是否阻塞:
在使用
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
函数获取信息时,可以通过指定timeout的值来决定是否阻塞[6](当timeout<0时,会无限期阻塞;当timeout=0时,会立即返回)。[《Linux/UNIX系统编程手册》Michael Kerrisk著 P1099]

Epoll:
关于Epoll是否阻塞:
在使用
epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
函数来获取是否有发生变化/事件的文件描述符时,可以通过指定timeout来指定该调用是否阻塞(当timeout=-1时,会无限期阻塞;当timeout=0时,会立即返回)。[1][《Linux/UNIX系统编程手册》Michael Kerrisk著 P1116]

关于Epoll是否同步:
当前是否有发生变化/事件的文件描述符需要通过
epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
显式地进行查询,因此不是异步;其他资料佐证了这一点[2]。参考资料
[1] http://man7.org/linux/man-pages/man2/epoll_wait.2.html
[2] https://www.zhihu.com/question/19732473/answer/26091478
[4] https://notes.shichao.io/unp/ch6/#synchronous-io-versus-asynchronous-io
[5] http://man7.org/linux/man-pages/man2/select.2.html
[6] http://man7.org/linux/man-pages/man2/poll.2.html
[7] 《Linux/UNIX系统编程手册》Michael Kerrisk著
所以正确的图表应该是:

triumphaxe commentedon Apr 16, 2018
说的不错,关于这个问题产生过很多误解。一个常见的事实是通过同步非阻塞I/O实现了宏观层面的异步操作,结果这里的I/O也被往往误认为是异步的了。
yanjinbin commentedon Mar 18, 2019
nice
zhengrenjie commentedon Feb 18, 2020
👍
mengxunQAQ commentedon Feb 6, 2021
cool
xuqing-er commentedon Jun 17, 2021
我认为epoll是没有同步或者异步的,关键取决于下层使用的是什么。例如如果将epoll和libaio结合,来检测一个操作是否完成,那也是异步的,此时操作已经完成;而如果利用epoll检测Socket是否有可读的数据,检测之后仍然需要线程去读取,这应该就是同步的。我的看法可能有错误,望批评指正。
xuqing-er commentedon Jun 17, 2021
另外同步或者异步需要从不同的层次来看:例如对于一个异步的RPC请求,不用等待请求完成,但下层仍然可以使用同步的操作进行数据的传输
zgg2001 commentedon Apr 1, 2022
👍
enjoyDay commentedon Oct 11, 2022
wedvefv commentedon Apr 6, 2023
阻塞的本质是cpu因为要等待耗时的操作 (比如磁盘io,网络io) ,cpu每一纳秒都能做很多事的好么,所以懒得等。所以当前进程就会被放到一个等待队列中睡眠等着,同时释放cpu给别的进程; 如果io处理完了,随眠进程会被唤醒从等待队列拿出来继续执行。
所以select,poll,epoll大多数时候还是用阻塞模式,虽然能设置超时;因为你查到没有就绪的事件要cpu资源也没用,就应该就绪睡觉。