我是 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"));
这似乎意味着在许多位置,它都没有正确重新启动系统调用。我错过了什么吗?对我来说,部分读取中断情况似乎比未读取情况更常见,并且随着请求的读取量变大,这种情况也会越来越常见。
最佳答案
But if it's interrupted when only some data was read the functions succeeds reading less than was requested.
您对这个主题的理解不完整。您需要仔细阅读此man page (其中的“信号处理程序中断系统调用和库函数”部分)。
特别注意“慢速”设备和本地磁盘(假设速度很快)之间的区别。
This would seem to mean it's, in numerous locations, not restarting the system call properly.
如果读取来自“快速”设备并且使用了SA_RESTART
,则系统调用将自动重新启动,并且不可能进行部分读取。
关于linux - glibc 和系统调用被信号中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35775979/