`
yong7181000
  • 浏览: 29808 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

睡眠--TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE

 
阅读更多
 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()创建一个等待队列的项
|--------------------------------------------------------|
|/* 'q' is the wait queue we wish to sleep on */ |
|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) {     /* condition is the event that we are waiting for */ 

3. Changes the process state to TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE.将进程的状态变更为TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE
|--------------------------------------------------------|
|       /* or TASK_UNINTERRUPTIBLE */            |
|    set_current_state(TASK_INTERRUPTIBLE); |
|--------------------------------------------------------|

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控制权
|--------------------------------------------------------|
|       if (signal_pending(current))                      |
|               /* handle signal */                           |
|--------------------------------------------------------|

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),进测等待事件是否真正发生.
|--------------------------------------------------------|
|       schedule();                                             |
|--------------------------------------------------------|

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);                     |
|--------------------------------------------------------|
    If the condition occurs before the task goes to sleep, the loop terminates, and the task does not erroneously go to sleep. Note that kernel code often has to perform various other tasks in the body of the loop. For example, it might need to release locks before calling schedule() and reacquire them after or react to other events. 
    如果在进程开始睡眠之前条件就已经达成了,那么循环会退出,进程不会存在错误的进入休眠的倾向。需要注意的是,内核代码在循环体内常常需要完成一些其他的 任务,比如,它可能在调用schedule()之前需要释放掉锁,而在这以后再重新获取它们,或者响应其他的事件。
    Waking is handled via wake_up(), which wakes up all the tasks waiting on the given wait queue. It calls try_to_wake_up(), which sets the task's state to TASK_RUNNING, calls activate_task() to add the task to a runqueue, and sets need_resched if the awakened task's priority is higher than the priority of the current task. The code that causes the event to occur typically calls wake_up() afterward. 
    唤醒操作通过函数wake_up进行,它会唤醒指定的等待队列上的所有进程。它调用函数try_to_wake_up,该函数负责将进程设置为 TASK_RUNNING状态,调用activate_task将此进程放入可执行队列,如果被唤醒的进程优先级比当前正在运行的进程的优先级高,还有设 置need_resched标志。通常哪段代码促使等待条件达成,它就负责随后调用wake_up()函数。 
    An important note about sleeping is that there are spurious wake-ups. Just because a task is awakened does not mean that the event for which the task is waiting has occurred; sleeping should always be handled in a loop that ensures that the condition for which the task is waiting has indeed occurred. 
    关于休眠有一点需要注意,存在虚假的唤醒。有时候进程被唤醒并不是因为它所等待的条件达成了(而是接受到了信号),所以才需要用一个循环处理来保证它等待的条件真正达成。 


[b]本文来自ChinaUnix博客,如果查看原文请点:http://www.cnblogs.com/parrynee/archive/2010/01/14/1648165.html
分享到:
评论

相关推荐

    深入理解Linux内核-勘误表

    勘误: 第三段和第一段重复, 而且还漏掉了很多东西, 原书第三段翻译如下: 处于TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE 状态的进程被分成很多类, 每一类代表一个事件, 在这种情况下, 进程状态不能充分描述这个进程,...

    同步互斥和 Linux 内核模块之C语言【100012226】

    以及统计系统中进程个数,包括统计系统中 TASK_RUNNING、TASK_INTERRUPTIBLE、TASK_UNINTERRUPTIBLE、TASK_ZOMBIE、TASK_STOPPED 等(还有其他状态)状态进程的个数。同时还需要编写一个用户态下执行的程序,格式化...

    Linux进程的睡眠和唤醒

    1 Linux进程的睡眠和唤醒 ...Linux 中的进程睡眠状态有两种:一种是可中断的睡眠状态,其状态标志位TASK_INTERRUPTIBLE; 另一种是不可中断 的睡眠状态,其状态标志位为TASK_UNINTERRUPTIBLE。可中断

    linux学习笔记v1.0 - 周立功开发板平台使用指令合集.docx

    Linux学习笔记 Linux学习笔记 1 1.4 Makefile 1 1.5 禁止鼠标滚轮复制操作 3 ... //ret = wait_event_interruptible(dev->r_wait, atomic_read(&dev->releasekey)); //if (ret) { // goto wait_error; //}

    pt7c4307 驱动

    if (test_and_set_bit (1, &rtc_status)) return -EBUSY; rtc_irq_data = 0; return 0; } static int rtc_release(struct inode *inode, struct file *file) { rtc_status = 0; return 0; } static int rtc...

    Simple Threading Library for Linux/Unix-开源

    一个简单的线程库。 对于Linux/Unix,通过Linux Kernel Space实现wait_queues、timers,在用户空间调度特定的函数调用,如wake_up_interruptible、interruptible_sleep_on、interruptible_sleep_on_timeout等。

    from-matlab-and-simulink-to-real-time-with-ti-dsps-1.2.pdf

    for example digital motor control and un-interruptible power supplies. We shall start here with a simple application. In this Laboratory, you will build a simulation model of a vehicle dynamics using...

    Kernel-Mode Driver Architecture Design Guide (Microsoft)-计算机科学

    Always Preemptible and Always Interruptible Multiprocessor-Safe Object-Based Packet-Driven I/O with Reusable IRPs Supporting Asynchronous I/O Sample Kernel-Mode Drivers Surface Team Driver ...

    Femt Operation System

    There is no separate idle task and most api function calls run in OS space. The OS is interruptible most of the time, if needed. There are tools to watch and protect the use of the stack of the tasks...

    Java2核心技术卷I+卷2:基础知识(第8版) 代码

    Interruptible Sockets 184 Sending E-Mail 191 Making URL Connections 196 Chapter 4: Database Programming 217 The Design of JDBC 218 The Structured Query Language 222 JDBC Configuration 227 ...

    tp-vagval-admin-services-1.4.0-RC1.zip

    interruptible-actor.zip,可中断演员

    matlab图形界面设计(英文原版)

    View Completed Layout and Its GUI M-File . . . . . . . . . . . . 2-10 Laying Out a Simple GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-11 Opening a New GUI in the Layout Editor . . . . ...

    UML建模之活动图介绍(Activity_Diagram)

    帮助大家学习UML 活动图有关的知识 UML建模之活动图介绍(Activity Diagram) 一、活动图的组成元素 Activity Diagram Element ...13、活动中断区域(Interruptible Activity Region) 14、泳道(Partition)

    需求侧2种可中断负荷备用市场报价策略的协调 (2008年)

    迄今为止,有关用户如何协调需求侧低电价与高赔偿2种可中断负荷(interruptible load, IL)备用市场报价策略方面的研究一直被长期忽视和孤立。用户在低电价与高赔偿2种II.市场中的收益特性相同,且属于风险性收益。为...

Global site tag (gtag.js) - Google Analytics