【问题标题】:Which read(2) errors are unrecoverable?哪些 read(2) 错误是不可恢复的?
【发布时间】:2016-05-19 11:09:03
【问题描述】:

man page for read(2) 列出了调用 read 时可能发生的许多错误。其中一些是良性的,例如EAGAIN。有些显然是不可恢复的,例如EBADFEFAULT。还有一些比较模糊,比如EIOEINTR。但是,手册页没有断言哪些错误是不可恢复的,哪些只是小问题。是否可以将所有错误归类为致命错误或重要错误?

posix specification for read() 与 linux 手册页非常相似。它还补充说:

没有提到在“不可恢复的错误”之后采取的措施。描述在硬件错误的情况下会发生什么被认为超出了 POSIX.1-2008 的范围。

在讨论 POSIX 系统时,尽管此类操作并未严格包含在范围内,但是否有关于在常见错误场景中如何处理的文献?编写可移植代码时是否有任何额外的注意事项?

【问题讨论】:

    标签: linux posix


    【解决方案1】:

    这些有点依赖于上下文:

    • EAGAIN 仅发生在非阻塞文件描述符上。除非您设置非阻塞标志,否则您可以将其与其他标志一起视为致命,因为它不应该发生。
    • EINTR 仅在您的进程收到它没有忽略的信号并且该进程仍然存在时才会发生。为此,您需要设置一个信号处理程序。除非您这样做,否则将其视为致命的。

    你提到的其他人也是致命的:

    • EIO 很可能是硬件问题。
    • EBADF 是您的程序中的一个问题:您传递了一个无效的文件描述符。
    • EFAULT 也是你程序中的一个问题:你传递了一个无效的缓冲区地址。

    简而言之:除非您执行异步 I/O 和信号处理等特殊操作,否则您可以将所有错误视为致命错误。

    【讨论】:

    • EINTR 应该始终以合理的代码进行处理,几乎没有任何情况表明正在发生可怕的事情,并且在很多情况下,适当的响应只是耸耸肩并重试。 EIO 也没有你想象的那么糟糕,并且可以重试。它可能表示硬件错误...或在网络关闭时访问网络驱动器...或在后台进程上从标准输入读取。有时你想放弃,有时不想。
    • 感谢您的信息。我开始熟悉一般情况。我只是想确保我的实施是详尽无遗的。如果它真的很简单,“除了EAGAIN(和EWOULDBLOCK)之外的任何东西都可以被认为是致命的”,太好了。但是,正如@hobbs 提到的,我对其中一些持怀疑态度,尤其是EIOEINTR(尽管正如你提到的,我的程序目前是单线程的)。例如,如果我收到ENOBUFS,内核是否有可能释放资源并且将来的调用会成功(类似于ENOMEM)?你知道任何参考资料吗?
    • @hobbs, EINTR 如果您没有安装信号处理程序,则不会发生 - 默认情况下会忽略信号,或者它会终止进程 - 所以单线程应用程序没有孩子可以将其视为致命的。
    • 好的代码不会假设它运行在没有人设置信号处理程序的进程中。这很容易改变:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 2018-08-29
    • 2011-12-19
    • 1970-01-01
    相关资源
    最近更新 更多