【发布时间】:2011-07-14 13:05:21
【问题描述】:
从阅读“read()”和“write()”调用的手册页来看,这些调用似乎会被信号中断,无论它们是否必须阻塞。
特别是假设
- 进程为某些信号建立处理程序。
- 在未设置“O_NONBLOCK”的情况下打开设备(例如终端 ....)(即在阻塞模式下运行)
- 然后该进程会进行“read()”系统调用以从设备中读取数据,结果会在内核空间中执行内核控制路径。
- 当进程在内核空间中执行其“read()”时,之前为其安装处理程序的信号被传递给该进程并调用其信号处理程序。
阅读手册页和 SUSv3 'System Interfaces volume (XSH)' 中的相应部分会发现:
我。如果 read() 在读取任何数据之前被信号中断(即它必须阻塞,因为没有数据可用),它会返回 -1 并将 'errno' 设置为 [EINTR]。
二。如果 read() 在成功读取一些数据后被信号中断(即可以立即开始为请求提供服务),它会返回读取的字节数
问题 A):
我是否正确假设在任何一种情况下(阻塞/无阻塞)信号的传递和处理对“read()”都不完全透明?
案例一。似乎可以理解,因为阻塞的“read()”通常会将进程置于“TASK_INTERRUPTIBLE”状态,这样在传递信号时,内核会将进程置于“TASK_RUNNING”状态。
但是,当“read()”不需要阻塞(情况 ii.)并在内核空间中处理请求时,我会认为信号的到达及其处理将是透明的,就像硬件中断的到达和正确处理将是。特别是我会假设,在传递信号时,进程将被临时置于 USER-MODE 以执行其信号处理程序,最终它将返回以完成处理中断的“read()”(在内核空间中) ) 以便 'read()' 运行到完成,之后进程返回到调用 'read()' 之后的点(在用户空间中),结果读取所有可用字节.
但是 ii.似乎暗示“读取()”被中断,因为数据立即可用但它返回返回“一些”数据(而不是全部)。
这就引出了我的第二个(也是最后一个)问题
问题 B):
如果我在 A) 下的假设是正确的,为什么“read()”会被中断,即使它不需要阻塞,因为有数据可以立即满足请求? 换句话说,为什么在执行信号处理程序后'read()'没有恢复,最终导致所有可用的数据(毕竟是可用的)被返回?
【问题讨论】:
标签: linux-kernel