事件驱动的IO和阻塞与非阻塞

Bob*_*erg 4 c io optimization nonblocking blocking

有人可以向我解释事件驱动的IO系统调用如select,poll和epoll如何与阻塞与非阻塞IO相关联?

我不明白这些概念是如何相关的 - 如果有的话

R..*_*R.. 6

它们在很大程度上是不相关的,除了您可能希望将非阻塞文件描述符与事件驱动的IO一起使用,原因如下:

  1. Linux的旧版本肯定在内核中存在错误,read即使在select指示套接字可读之后也可以阻塞(它发生在UDP套接字和具有错误校验和的数据包).当前版本的Linux 可能仍然有一些这样的错误; 我不确定.

  2. 如果其他进程有可能访问您的文件描述符并且将对它们进行读/写,或者如果您的程序是多线程的并且其他线程可能这样做,则在select确定文件描述符是可读的之间存在竞争条件/ writable和你的程序在其上执行IO,这可能会导致阻塞.

  3. 你几乎肯定想在调用之前使套接字无阻塞connect; 否则你将阻止,直到建立连接.使用select写来确定当它成功连接,并select为错误,以确定是否连接失败.


Bla*_*iev 6

select系统调用是在几乎所有的Unix的支持,并提供了用户级应用观看了一组描述符,并获得有关此组的子集,准备好读/写信息.它的特殊界面有点笨拙,大多数内核中的实现充其量只是平庸.

epoll仅出于同样的目的在Linux中提供,但select在效率和编程接口方面是一个巨大的改进.其他Unix也有专门的调用.

也就是说,事件驱动的IO系统调用不需要阻塞或非阻塞描述符.阻塞是影响系统调用,就像一个行为read,write,acceptconnect.select并且epoll_wait确实有阻塞超时,但这与描述符无关.

当然,使用带有阻塞描述符的这些事件驱动的系统调用有点奇怪,因为您可能希望在收到通知可用后立即读取数据而不会阻塞.在获得通知准备就绪后,始终依赖阻塞描述符不会阻塞,这有点冒险,因为竞争条件是可能的.

非阻塞,事件驱动的IO可以使服务器应用程序更加高效,因为每个描述符(连接)都不需要线程.在性能方面将Apache Web服务器与Nginx或Lighttpd进行比较,您将看到好处.