【问题标题】:glibc and system calls interrupted by signalsglibc 和系统调用被信号中断
【发布时间】:2016-03-03 15:16:17
【问题描述】:

我是 Linux 新手,正在学习系统调用和信号。例如read 系统调用可以被信号中断。如果它在读取任何内容之前被中断,它将失败并将errno 设置为EINTR。在glibc 中,这主要由TEMP_FAILURE_RETRY 宏处理。但是,如果它在仅读取一些数据时被中断,则函数成功读取的数据少于请求的数据。在这种情况下,调用者应该为丢失的部分发出另一个read,继续此操作直到读取所有数据。然而,glibc 源包含许多这样的调用:

if (TEMP_FAILURE_RETRY (read (fd, &word, 4)) != 4)
    error (EXIT_FAILURE, errno, _("cannot read header"));

这似乎意味着它在许多地方都没有正确地重新启动系统调用。我错过了什么吗?在我看来,部分读取中断的情况似乎比尚未读取的情况更常见,并且随着读取请求的数量越来越大。

【问题讨论】:

    标签: linux unix signals glibc


    【解决方案1】:

    但是如果它在仅读取一些数据时被中断,则函数成功读取的数据少于请求的数据。

    您对该主题的理解不完整。您需要仔细阅读此man page(其中的“信号处理程序中断系统调用和库函数”部分)。

    特别注意“慢”设备和本地磁盘(假定为快)之间的区别。

    这似乎意味着它在许多地方都没有正确地重新启动系统调用。

    如果读取来自“快速”设备并且使用了SA_RESTART,则系统调用将自动重新启动,并且不可能进行部分读取。

    【讨论】:

    • 感谢您的回复,这确实对问题有所了解。我肯定需要更多地研究它。来自 Windows 开发背景的我不得不承认发现 *nix 的信号/系统调用机制(以及两者之间的交互)令人困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 2014-09-10
    • 2013-04-11
    • 1970-01-01
    相关资源
    最近更新 更多