睡眠--TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE
休眠有两种相关的进程状态: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()创建一个等待队列的项
|--------------------------------------------------------|
|DECLARE_WAITQUEUE(wait, current); |
|--------------------------------------------------------|
|--------------------------------------------------------|
|add_wait_queue(q, &wait); |
|--------------------------------------------------------|
while (!condition) { /* condition is the event that we are waiting for */
|--------------------------------------------------------|
| /* or TASK_UNINTERRUPTIBLE */ |
| set_current_state(TASK_INTERRUPTIBLE); |
|--------------------------------------------------------|
|--------------------------------------------------------|
| if (signal_pending(current)) |
| /* handle signal */ |
|--------------------------------------------------------|
|--------------------------------------------------------|
| schedule(); |
|--------------------------------------------------------|
}
|--------------------------------------------------------|
|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.
关于休眠有一点需要注意,存在虚假的唤醒。有时候进程被唤醒并不是因为它所等待的条件达成了(而是接受到了信号),所以才需要用一个循环处理来保证它等待的条件真正达成。
睡眠--TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE的更多相关文章
- TASK_INTERRUPTIBLE 和TASK_UNINTERRUPTIBLE
TASK_INTERRUPTIBLE 和TASK_UNINTERRUPTIBLE TASK_INTERRUPTIBLE 和TASK_UNINTERRUPTIBLE 的区别 TASK_INTERRUPT ...
- Linux进程的睡眠和唤醒简析
COPY FROM:http://www.2cto.com/os/201204/127771.html 1 Linux进程的睡眠和唤醒 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在 ...
- linux 内核睡眠与唤醒
休眠(被阻塞)的进程处于一个特殊的不可执行状态.进程休眠由多种原因,但肯定都是为了等待一些事件.事件可能是一 段时间从文件I/O读取更多数据,或者是某个硬件事件.一个进程还由可能在尝试获取一个已被占用 ...
- Socket层实现系列 — 睡眠驱动的同步等待
主要内容:Socket的同步等待机制,connect和accept等待的实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 概述 socket上定义了 ...
- Linux进程的睡眠和唤醒
1 Linux进程的睡眠和唤醒 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING.一旦一个运行中的进程时间片用完, ...
- linux一个进程如何睡眠
如果我们深入 <linux/wait.h>, 你见到在 wait_queue_head_t 类型后面的数据结构是非 常简单的; 它包含一个自旋锁和一个链表. 这个链表是一个等待队列入口, ...
- android开发读书笔记
第九章心得: HAL ( Hardware Abstraction Layer,硬件抽象腔,〉是建立在Linux驱动之上的一套翻字库.这套程序 j率并不属于 Linux 内核, 而是属于 Linux ...
- 《Linux内核分析》之第四章读书笔记
4.1多任务 多任务操作系统:同时并发地交互执行多个进程的操作系统 多任务操作系统会使多个进程处于堵塞或者睡眠状态.这些任务尽管位于内存,但是并不处于可运行状态.这些进程利用内核堵塞自己,直到某一事件 ...
- 20135202闫佳歆--week 8 课本第4章学习笔记
第四章 进程调度 一.多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统. 多任务操作系统使多个进程处于堵塞或者睡眠状态,实际不被投入执行,这些任务尽管位于内存,但是并不处于可运行状态. ...
随机推荐
- CodeBlock使用技巧
CodeBlock是一款采用C++编写的完全开源.功能强大的IDE,工欲善其事必先利其器,为了更加方便后期的开发调试,下面先就网上的一些 官方主页地址为: http://www.codebloc ...
- Unity编程回忆录之控制物体移动
最新心血来潮,然后开始学习Unity3D游戏开发引擎,对于一个主流的跨平台3D游戏开发引擎,我已经深深的为他着迷了,于是果断的开始学习这个引擎,而且刚刚预装的游戏引擎最新版中4.3版本已经开始原生支持 ...
- C#对象转JSON字符串和JSON字符串转对象
namespace Net.String.ConsoleApplication { using System; using System.Data; using System.Collections; ...
- 在windows服务器中,将MongoDB服务化。
将mongodb在windows中服务化,就是将其注册成一个服务组件,并可以设置成,手动/自动 启动. 一般的我们都会在command窗口运行如下: d:\mongodb\bin>mongod ...
- js判断屏幕分辨率的代码
通过下面的代码判断分辨率 <script language="JavaScript"> <!-- Begin function redirectPage() { ...
- putty 代理设置
代理分 http 和 socket 代理. IE Internet属性-> 连接 -> 局域网设置 普通HTTP代理 直接输入IP,端口 socket 代理 点高级 套接字设置 安装好P ...
- Python学习笔记2——模块的发布
1.为模块nester创建文件夹nester,其中包含:nester.py(模块文件): """这是"nester.py"模块,提供了一个名为prin ...
- javascript看你能够做对几题
http://ourjs.com/detail/52fb82e13bd19c4814000001
- 【BZOJ 1798】 [Ahoi2009]Seq 维护序列seq
Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- python学习笔记23(时间与日期 (time, datetime包))
Python提供了多个内置模块用于操作日期时间,像calendar,time,datetime. time包 time包基于C语言的库函数(library functions).Python的解释器通 ...