我很难理解 LDD3 的以下陈述。 “down_interruptible - 它允许正在等待信号量的用户空间进程被用户中断”。
用户空间应用程序不会直接进行 down_interruptible 调用。假设设备驱动程序这样做了,并且设备驱动程序通过调用 down_interruptible 触发应用程序进入睡眠状态。现在,发送给用户空间应用程序的信号如何从睡眠状态调用应用程序,因为它是调用 down_interruptible 的设备驱动程序而不是应用程序。
有人请向我澄清这一点。
任何设备驱动程序都不会自行运行,设备驱动程序通过系统调用代表进程运行。
假设任何设备驱动程序调用
down_interruptible();
,这意味着如果信号量不可用,则相应的进程将被放入信号量等待队列中。
任务状态将更改为TASK_INTERRUPTIBLE
,并且调度程序将被调用来运行任何其他进程。现在,睡眠进程可以通过等待的事件(信号量)或信号来唤醒。
示例:
kill -SIGINT <pid>
将导致进程将其状态更改为TASK_RUNNING
,并将该进程添加到运行队列。
这是等待队列的伪代码,它显示了进程如何等待任何事件。
/* ‘q’ is the wait queue we wish to sleep on */
DEFINE_WAIT(wait);
add_wait_queue(q, &wait);
while (!condition) /* condition is the event that we are waiting for */
{
prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);
if (!signal_pending(current))
{
schedule();
continue;
}
ret = -ERESTARTSYS;
}
finish_wait(&q, &wait);
在您的示例中,进程被添加到等待队列并等待条件释放它。同时它还会检查是否有任何未决信号,如果有,它将返回
-ERESTARTSYS
,否则再次进入睡眠状态。