- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
2 Linux进程状态
【2】
Linux进程休眠和唤醒
当进程以阻塞的方式通信,在得到结果前进程会挂起休眠。为了将进程以一种安全的方式进入休眠,我们需要牢记两条规则:一、永远不要在原子上下文中进入休眠。二、进程休眠后,对环境一无所知。唤醒后,必须再次检查以确保我们等待的条件真正为真
简单休眠完成唤醒任务的代码还必须能够找到我们的进程,这样才能唤醒休眠的进程。需要维护一个称为等待队列的数据结构。等待队列就是一个进程链表,其中包含了等待某个特定事件的所有进程。linux维护一个“等待队列头”来管理,wait_queue_head_t,定义在linux/wait.hstruct? __wait_queue_head {?wq_lock_t? lock;?struct? list_head? task_list;};typedef? struct __wait_queue_head? wait_queue_head_t;初始化方法:静态方法:DECLARE_WAIT_QUEUE_HEAD(name)动态方法:wait_queue_head_t my_queue;init_waitqueue_head(my_queue);
linux中最简单的休眠方式是下面的宏,?wait_event(queue, condition)? /*进程将被置于非中断休眠(uninterruptible sleep)*/wait_event_interruptible(queue, condition) /*进程可被信号中断休眠,返回非0值表示休眠被信号中断*/wait_event_timeout(queue, condition, timeout)??? /*等待限定时间jiffy,condition满足其一返回0*/wait_event_interruptible_timeout(queue, condition, timeout)queue是等待队列头,传值方式condition是任意一个布尔表达式,在休眠前后多次对condition求值,为真则唤醒
唤醒进程的基本函数是wake_upvoid wake_up(wait_queue_head_t *queue);??? /*唤醒等待在给定queue上的所有进程*/void wake_up_interruptible(wait_queue_head_t *queue);
实践中,一般是wait_event和wake_up,wait_event_interruptible和wake_up_interruptible成对使用
高级休眠将进程置于休眠的步骤:(1)分配和初始化一个 wait_queue_t 结构, 随后将其添加到正确的等待队列
struct __wait_queue {??????? unsigned int flags;#define WQ_FLAG_EXCLUSIVE?????? 0x01??????? void *private;??????? wait_queue_func_t func;??????? struct list_head task_list;};typedef struct __wait_queue wait_queue_t;(2)设置进程状态,标记为休眠。2.6内核中,使用下面的函数:????? void set_current_state(int new_state);??? 在 linux/sched.h 中定义有几个任务状态:TASK_RUNNING 意思是进程能够运行。有 2 个状态指示一个进程是?? 在睡眠: TASK_INTERRUPTIBLE 和 TASK_UNTINTERRUPTIBLE
(3)最后一步是放弃处理器。 但必须先检查进入休眠的条件。如果不做检查会引入竞态: 如果在忙于上面的这个过程时有其他的线程刚刚试图唤醒你,你可能错过唤醒且长时间休眠。因此典型的代码下if (!condition)????? schedule( );??? /*调用调度器,并让出CPU*/如果代码只是从 schedule 返回,则进程处于TASK_RUNNING 状态。 如果不需睡眠而跳过对 schedule 的调用,必须将任务状态重置为 TASK_RUNNING,还必要从等待队列中去除这个进程,否则它可能被多次唤醒。
手工休眠上面的进程休眠步骤可通过手工设置:?(1)创建和初始化一个等待队列。常由宏定义完成:DEFINE_WAIT(my_wait);name 是等待队列入口项的名字. 也可以用2步来做:wait_queue_t my_wait;init_wait(my_wait);常用的做法是放一个 DEFINE_W
文档评论(0)