2016-03-03 35 views
1

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

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

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

回答

1

但是,如果仅在读取某些数据时中断,则函数会成功读取小于请求的数据。

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

特别要注意“慢速”设备和本地磁盘(假设速度很快)之间的区别。

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

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

+0

感谢您的回复,这确实解决了一些问题。我一定要更多地研究它。从Windows开发背景来看,我不得不承认找到* nix的信号/系统调用机制(以及两者之间的交互)困惑。 – Steve