【发布时间】:2019-10-01 19:33:46
【问题描述】:
如 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 状态的阻塞系统调用。
【问题讨论】:
标签: linux linux-kernel kernel signals system-calls