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

时间:2011-04-27 16:15:17

标签: c optimization io blocking nonblocking

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

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

3 个答案:

答案 0 :(得分:6)

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

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

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

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

答案 1 :(得分:5)

几乎所有Unix都支持select系统调用,并为用户空间应用程序提供监视一组描述符的方法,并获取有关该组的哪个子集已准备好进行读/写的信息。它的特殊界面有点笨拙,大多数内核中的实现充其量只是平庸。

epoll仅在Linux中提供用于相同目的,但在效率和编程接口方面比select有很大改进。其他Unix也有专门的调用。

也就是说,事件驱动的IO系统调用不需要阻塞或非阻塞描述符。阻止是一种影响readwriteacceptconnect等系统调用的行为。 selectepoll_wait确实有阻止超时,但这与描述符无关。

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

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

答案 2 :(得分:0)

select和类似的函数(你提到过几个)通常用于在事件驱动的系统中实现事件循环。

即,不是直接从套接字或文件中读取() - 如果没有数据可用,则可能阻塞,应用程序在多个文件描述符上调用select(),等待任何一个上的数据他们

当文件描述符可用时,您可以确保数据可用且read()操作不会阻止。

这是一种同时处理来自多个源的数据而无需使用多个线程的方法。