你能否解释一下事件驱动的IO系统调用(例如select、poll和epoll)与阻塞式和非阻塞式IO有什么关系?
我不理解这些概念是否有关联。
你能否解释一下事件驱动的IO系统调用(例如select、poll和epoll)与阻塞式和非阻塞式IO有什么关系?
我不理解这些概念是否有关联。
select
系统调用几乎支持所有的Unix系统,提供了一种用户空间应用程序监视一组描述符并获取关于哪个子集已经准备好读/写的信息的方法。它的特定接口有点笨拙,在大多数内核中的实现都很差。
epoll
仅在Linux中提供相同的功能,但在效率和编程接口方面比select
有了很大的改进。其他Unix系统也有他们专门的调用。
话虽如此,事件驱动的IO系统调用不需要阻塞或非阻塞描述符。阻塞是影响像read
、write
、accept
和connect
这样的系统调用的行为。 select
和epoll_wait
确实有阻塞超时,但那与描述符无关。
当然,使用这些事件驱动的系统调用与阻塞描述符有点奇怪,因为您期望在通知其可用后,可以立即读取数据而不会阻塞。总是依赖于一个阻塞描述符在通知其准备就绪后不会阻塞是有点冒险的,因为可能存在竞争条件。
非阻塞的事件驱动IO可以使服务器应用程序更加高效,因为不需要为每个描述符(连接)使用线程。比较Apache Web服务器与Nginx或Lighttpd在性能方面的差异,您会看到其好处。
pthread_create
的成本仅约等于 2-3 次 open
调用,当然,如果你已经将线程阻塞在 accept
上等待连接到来,那么成本甚至更低。 - R.. GitHub STOP HELPING ICEselect
和类似的函数(您提到了几个)通常用于在事件驱动系统中实现事件循环。
也就是说,应用程序不直接从套接字或文件中进行read()操作,以避免可能会阻塞,而是调用select()在多个文件描述符上等待数据可用于任何一个。
当文件描述符变为可用状态时,您可以确信数据已经可用,read()操作将不会阻塞。
这是一种在不使用多个线程的情况下同时处理来自多个来源的数据的方法。
select
和accept
之间中断连接尝试。 - Nikolai Fetissov