原文地址:http://blog.sina.com.cn/s/blog_765e277901017no8.html
Two states are associated with sleeping, TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE. They differ only in that tasks in the TASK_UNINTERRUPTIBLE state ignore signals, whereas tasks in the TASK_INTERRUPTIBLE state wake up prematurely and respond to a signal if one is issued. Both types of sleeping tasks sit on a wait queue, waiting for an event to occur, and are not runnable.
休眠有两种相关的进程状态:TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE。它们的惟一却不是处于TASK_UNINTERRUPTIBLE状态的进程会忽略信号,而处于TASK_INTERRUPTIBLE状态的进程如果收到信号会被唤醒并处理信号(然后再次进入等待睡眠状态)。两种状态的进程位于同一个等待队列上,等待某些事件,不能够运行。
因为等待事件而进入睡眠状态的方法:
the recommended method for sleeping in the kernel is a bit more complicated.
在内核中进行休眠的推荐操作相对复杂一些.
The task performs the following steps to add itself to a wait queue:
进程通过执行下面几步将自己加入到一个等待队列中:
1. Creates a wait queue entry via DECLARE_WAITQUEUE().调用DECLARE_WAITQUEUE()创建一个等待队列的项
|--------------------------------------------------------|
因为等待事件而进入睡眠状态的方法:
The task performs the following steps to add itself to a wait queue:
进程通过执行下面几步将自己加入到一个等待队列中:
1. Creates a wait queue entry via DECLARE_WAITQUEUE().调用DECLARE_WAITQUEUE()创建一个等待队列的项
|--------------------------------------------------------|
| |
|DECLARE_WAITQUEUE(wait, current); |
|--------------------------------------------------------|
|DECLARE_WAITQUEUE(wait, current);
|--------------------------------------------------------|
2. Adds itself to a wait queue via add_wait_queue(). This wait queue awakens the process when the condition for which it is waiting occurs. Of course, there needs to be code elsewhere that calls wake_up() on the queue when the event actually does occur.调用add_wait_queue()把自己加入到队列中。该队列在进程等待的条件满足时唤醒它。当然我们必须在其他地方撰写相关代码,在事件发生时,对等待队列执行wake_up()操作
|--------------------------------------------------------|
|add_wait_queue(q, &wait); |
|--------------------------------------------------------|
while (!condition) {
|--------------------------------------------------------|
|add_wait_queue(q, &wait);
|--------------------------------------------------------|
while (!condition) {
3. Changes the process state to TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE.将进程的状态变更为TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE
|--------------------------------------------------------|
|
|
|--------------------------------------------------------|
4. If the state is set to TASK_INTERRUPTIBLE, a signal wakes the process up. This is called a spurious wake up (a wake-up not caused by the occurrence of the event). So check and handle signals.如果状态被设置为TASK_INTERRUPTIBLE,则信号可以唤醒进程(信号和事件都可以唤醒该进程)。这就是所谓的伪唤醒(唤醒不是因为事件的发生,而是由信号唤醒的),因此检查并处理信号。注: 信号和等待事件都可以唤醒处于 TASK_INTERRUPTIBLE 状态的进程,信号唤醒该进程为伪唤醒; 该进程被唤醒后,如果 (!condition) 结果为真,则说明该进程不是由等待事件唤醒的, 而是由信号唤醒的。 所以该进程处理信号后将再次让出CPU控制权
|--------------------------------------------------------|
|
|
|--------------------------------------------------------|
5. Tests whether the condition is true. If it is, there is no need to sleep. If it is not true, the task calls schedule().本进程在此处交出CPU控制权,如果该进程再次被唤醒,将从while循环结尾处继续执行,因而将回到while循环的开始处while (!condition),进测等待事件是否真正发生.
|--------------------------------------------------------|
|
|--------------------------------------------------------|
}
6. Now that the condition is true, the task can set itself to TASK_RUNNING and remove itself from the wait queue via remove_wait_queue().
|--------------------------------------------------------|
|set_current_state(TASK_RUNNING);
|remove_wait_queue(q, &wait);
|--------------------------------------------------------|