如果一个 I/O 函数不能因 EINTR 而失败,这是不是意味着它永远不会阻塞?
Posted
技术标签:
【中文标题】如果一个 I/O 函数不能因 EINTR 而失败,这是不是意味着它永远不会阻塞?【英文标题】:If an I/O function cannot fail with EINTR, does that mean it never blocks?如果一个 I/O 函数不能因 EINTR 而失败,这是否意味着它永远不会阻塞? 【发布时间】:2015-07-12 11:53:05 【问题描述】:例如,考虑fdopen
。我一直在想,如果文件描述符参数引用管道或套接字,是否有可能阻塞。谷歌搜索没有发现任何有用的东西。一方面,在我看来它不应该阻塞,因为它只是将流与文件描述符“关联”。另一方面,我想知道实现是否有许可在 fdopen
调用时预填充缓冲区,如果新打开的管道或套接字还没有可供读取的数据,这可能会阻塞。
可能的错误是EMFILE
、EBADF
、EINVAL
和ENOMEM
。我假设任何阻塞 I/O 函数都可能被信号中断,因此如果 fdopen
可能阻塞,那么 EINTR
也将作为可能的错误给出。既然不是这样,我可以假设fdopen
永远不会阻塞吗?这是否也适用于其他 I/O 功能?
【问题讨论】:
【参考方案1】:fdopen() 是一个 libc 调用,它使用诸如 fcntl() 之类的各种系统调用来检查文件的状态。与 fdopen() 返回的相比,这些系统调用可以阻止和/或返回额外的错误代码。例如,fcntl() 可以阻塞并返回 EINTR。 fdopen() 的实现透明地处理可恢复的错误条件。
底线,fdopen() 可以阻塞,因为它至少使用了一个阻塞系统调用。同样的道理也适用于其他与 I/O 相关的 libc 函数。
【讨论】:
以上是关于如果一个 I/O 函数不能因 EINTR 而失败,这是不是意味着它永远不会阻塞?的主要内容,如果未能解决你的问题,请参考以下文章
对 websocket 服务器的请求失败并出现 WebSocket I/O 错误:读取超时