如signal(7)手册页所述,
Interruption of system calls and library functions by signal handlers
If a signal handler is invoked while a system call or library function call is blocked, then either:
* the call is automatically restarted after the signal handler returns; or
* the call fails with the error EINTR.
Which of these two behaviors occurs depends on the interface and whether or not the signal handler was established using the SA_RESTART flag (see sigaction(2)). The details vary across UNIX systems; below, the details for
Linux.
If a blocked call to one of the following interfaces is interrupted by a signal handler, then the call will be automatically restarted after the signal handler returns if the SA_RESTART flag was used; otherwise the call will
fail with the error EINTR:
* read(2), readv(2), write(2), writev(2), and ioctl(2) calls on "slow" devices. A "slow" device is one where the I/O call may block for an indefinite time, for example, a terminal, pipe, or socket. If an I/O call on a
slow device has already transferred some data by the time it is interrupted by a signal handler, then the call will return a success status (normally, the number of bytes transferred). Note that a (local) disk is not a
slow device according to this definition; I/O operations on disk devices are not interrupted by signals.
如上所述,信号处理程序中断了对以下接口之一(读,写)的阻塞调用,如果使用SA_RESTART标志,则信号处理程序返回后,该调用将自动重新启动,这意味着如果阻塞了读写系统调用,则进程必须处于TASK_INTERRUPTIBLE状态。
但是当我试图找出使进程处于TASK_UNINTERRUPTIBLE状态的阻塞系统调用时,我发现了https://unix.stackexchange.com/questions/62697/why-is-i-o-uninterruptible和Why doing I/O in Linux is uninterruptible?,并且在这两个地方都提到了阻塞的I / O调用(读,写)将一个进程放入TASK_UNINTERRUPTIBLE。
这里也提到了它:https://access.redhat.com/sites/default/files/attachments/processstates_20120831.pdf
The Uninterruptible state is mostly used by device drivers waiting for disk or network I/O. When the process
is sleeping uninterruptibly, signals accumulated during the sleep are noticed when the process returns from
the system call or trap. In Linux systems. the command ps -l uses the letter D in the state field (S) to
indicate that the process is in an Uninterruptible sleep state. In that case, the process state flag is set as
follows:
p->state = TASK_UNINTERRUPTABLE
LEARN MORE: Read more about D states in the Red Hat Knowledgebase:
https://access.redhat.com/knowledge/solutions/59989/
有点令人困惑。
我还想知道其他阻塞的系统调用,这些调用会使进程进入TASK_UNINTERRUPTIBLE状态。
答案 0 :(得分:3)
对于read(2)
或write(2)
家族的系统调用,睡眠类型取决于所访问文件的类型。在您引用的文档中,“慢速”设备是指read/write
可以中断睡眠的设备,而“快速”设备是指可以不间断睡眠的设备(“磁盘等待”的不间断睡眠状态称为D
”,因为最初read/write
在磁盘文件上是这种睡眠的最常见原因。
请注意,“阻止”在技术上仅指可中断的睡眠。
几乎所有系统调用都可以进入不间断的睡眠,因为(在其他情况下)这可能在进程需要获取保护内部内核资源的锁时发生。通常,这种不间断的睡眠是如此短暂,以至于您不会注意到它。