linux进程的睡眠和唤醒.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
linux进程的睡眠和唤醒

LKD中的讲解 休眠(被阻塞)的进程处于一个特殊的不可执行状态。 这点非常重要,否则,没有这种特殊状态的话,调度程序就可能选出一个本不愿意被执行的进程,更糟糕的是,休眠就必须以轮询的方式实现了。进程休眠有各种原 因,但肯定都是为了等待一些事件。事件可能是一段时间、从文件I/O读更多数据,或者是某个硬件事件。一个进程还有可能在尝试获得一个已经占用的内核信号 量时被迫进入休眠。休眠的一个常见原因就是文件I/O -- 如进程对一个文件执行了read()操作,而这需要从磁盘里读取。还有,进程在获取键盘输入的时候也需要等待。无论哪种情况,内核的操作都相同:进程把它 自己标记成休眠状态,把自己从可执行队列移出,放入等待队列,然后调用schedule()选择和执行一个其他进程。唤醒的进程刚好相反:进程被设置为可 执行状态,然后再从等待队列中移到可执行队列。 ? ? 休眠有两种相关的进程状态:TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE。它们的惟一区别是处于TASK_UNINTERRUPTIBLE状态的进程会忽略信号,而处于 TASK_INTERRUPTIBLE状态的进程如果收到信号会被唤醒并处理信号(然后再次进入等待睡眠状态)。两种状态的进程位于同一个等待队列上,等 待某些事件,不能够运行。 ? ?? ?? ? ? ? 休眠通过等待队列进行处理。等待队列是由等待某些事件发生的进程组成的简单链表。内核用wake_queue_head_t来代表等待队列。等待队列可以 通过DECLARE_WAITQUEUE()静态创建,也可以有init_waitqueue_head()动态创建。进程把自己放入等待队列中并设置成 不可执行状态。等与等待队列相关的事件发生的时候,队列上的进程会被唤醒。为了避免产生竞争条件,休眠和唤醒的实现不能有纰漏。 ? ???针对休眠,以前曾经使用过一些简单的接口。但那些接口会带来竞争条件;有可能导致在判断条件变为真后进程却开始了休眠,那样就会使进程无限期地休眠下去。所以,在内核中进行休眠的推荐操作相对复杂一些. 进程通过执行下面几步将自己加入到一个等待队列中: --------------------------------------------------------- 1. 调用DECLARE_WAITQUEUE()创建一个等待队列的项 |------------------------------------------------| |/* q is the wait queue we wish to sleep on */ | | DECLARE_WAITQUEUE (wait, current);? ?? ?? ?? ?? ?? ???| |------------------------------------------------| 2. 调用add_wait_queue()把自己加入到队列中。该队列在进程等待的条件满足时唤醒它。当然我们必须在其他地方撰写相关代码,在事件发生时,对等待队列执行wake_up()操作 |-----------------------------| | add_wait_queue (q, wait);? ?? ?? ?| |-----------------------------| while (!condition) {? ?? ?? ? /* condition is the event that we are waiting for */ 3. 将进程的状态变更为TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE |----------------------------------------------| |? ?? ?? ?? ?/* or TASK_UNINTERRUPTIBLE */? ?? ?? ?? ?? ?| |? ?? ?? ?? ?set_current_state(TASK_INTERRUPTIBLE); | |----------------------------------------------| 4. 如果状态被设置为TASK_INTERRUPTIBLE,则信号可以唤醒进程(信号和事件都可以唤醒该进程)。这就是所谓的伪唤醒(唤醒不是因为事件的发生,而是由信号唤醒的),因此检查并处理信号。 注: 信号和等待事件都可以唤醒处于TASK_INTERRUPTIBLE状态的进程,信号唤醒该进程为伪唤醒;该进程被唤醒后,如果(!condition)结果为真,则说明该进程不是由等待事件唤醒的,而是由信号唤醒的。所以该进程处理信号后将再次让出CPU控制权 |----------

文档评论(0)

2017ll + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档