睡眠--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章学习笔记
第四章 进程调度 一.多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统. 多任务操作系统使多个进程处于堵塞或者睡眠状态,实际不被投入执行,这些任务尽管位于内存,但是并不处于可运行状态. ...
随机推荐
- 隐藏内容_网络推广_seo中级视频教程详解
课程背景:SEO(Search Engine Optimization),汉译为搜索引擎优化.搜索引擎优化是一种利用搜索引擎的搜索规则来提高目的网站在有关搜索引擎内的排名的方式.SEO目的理解是:为网 ...
- Android 源码VecotorDrawable
1 R.styleable.VectorDrawable_viewportWidth 该资源的名字并非VectorDrawable_viewportWidth 而是 attrs.xml 下的声明 &l ...
- 【转】 .NET中STAThread和MTAThread
ref:http://blog.csdn.net/dyllove98/article/details/9735955 1 COM中的公寓 本文讨论进程内COM组件.以一个示例直观演示STAThread ...
- 【Android】Android SDK在线更新镜像服务器
Android SDK在线更新镜像服务器 中国科学院开源协会镜像站地址: IPV4/IPV6: http://mirrors.opencas.cn 端口:80 IPV4/IPV6: http://mi ...
- [转帖]译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)
原文链接:http://norke.blog.163.com/blog/static/276572082011828104315941/ 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我 ...
- ACE_linux:UDP通信
1.涉及类 ACE_INET_Addr//ACE网络地址ACE_SOCK_Dgram//ACE报文 2.简介 UDP通信时无需像TCP那样建立连接和关闭连接,TCP编程时需要通过accept和conn ...
- Centos6.4 安装NLTK
NLTK 安装链接 http://www.nltk.org/install.html 不知道什么原因打不开pypi 的网站 http://pypi.python.org/pypi/setuptool ...
- Oracle中SAVEPOINT和ROLLBACK用法
savepoint是事务内部允许部分rollback的标志符.因为事务中对记录做了修改,我们可以在事务中创建savepoint来标识不同的点.如果遇到错误,就可以rollback到不同的点或直接回来事 ...
- oracle中的dual表详解
oracle中的dual表详解 1.DUAL表的用途 Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的Select语句块中 --查看当前连接用户 SQL> s ...
- iframe 刷新
iframe刷新父页面 parent.location.reload(); iframe 一个子页面操作过后,刷新指定子页面 parent.frames('ifrmname').location.re ...