- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
linux内核源代码-进程管理及调度详解
优先级计算方法 在 2.4 内核中,优先级的计算和候选进程的选择集中在调度器中进行,无法保证调度器的执行时间,这一点在前面介绍 runqueue 数据结构的时候已经提及。2.6 内核中候选进程是直接从已按算法排序的优先级队列数组中选取出来的,而优先级的计算则分散到多处进行。这一节分成两个部分对这种新的优先级计算方法进行描述,一部分是优先级计算过程,一部分是优先级计算(以及进程入队)的时机。 1)优先级计算过程 动态优先级的计算主要由 effect_prio() 函数完成,该函数实现相当简单,从中可见非实时进程的优先级仅决定于静态优先级(static_prio)和进程的sleep_avg 值两个因素,而实时进程的优先级实际上是在 setscheduler() 中设置的(详见“调度系统的实时性能”,以下仅考虑非实时进程),且一经设定就不再改变。相比较而言,2.4 的 goodness() 函数甚至要更加复杂,它考虑的 CPU Cache 失效开销和内存切换的开销这里都已经不再考虑。 2.6 的动态优先级算法的实现关键在 sleep_avg 变量上,在 effective_prio() 中,sleep_avg 的范围是 0~MAX_SLEEP_AVG,经过以下公式转换后变成-MAX_BONUS/2~MAX_BONUS/2 之间的 bonus: (NS_TO_JIFFIES((p)-sleep_avg) * MAX_BONUS / MAX_SLEEP_AVG) - MAX_BONUS/2 如下图所示: 再用这个 bonus 去减静态优先级就得到进程的动态优先级(并限制在 MAX_RT_PRIO和MAX_PRIO 之间),bonus 越小,动态优先级数值越大,优先级越低。也就是说,sleep_avg 越大,优先级也越高。 2) 优先级计算时机 优先级的计算不再集中在调度器选择候选进程的时候进行了,只要进程状态发生改变,核心就有可能计算并设置进程的动态优先级: a) 创建进程 在wake_up_forked_process()中,子进程继承了父进程的动态优先级,并添加到父进程所在的就绪队列中。 如果父进程不在任何就绪队列中(例如它是 IDLE 进程),那么就通过 effect_prio() 函数计算出子进程的优先级,而后根据计算结果将子进程放置到相应的就绪队列中。 b) 唤醒休眠进程 核心调用 recalc_task_prio() 设置从休眠状态中醒来的进程的动态优先级,再根据优先级放置到相应就绪队列中。 c) 调度到从 TASK_INTERRUPTIBLE 状态中被唤醒的进程 实际上此时调度器已经选定了候选进程,但考虑到这一类型的进程很有可能是交互式进程,因此此时仍然调用 recalc_task_prio() 对该进程的优先级进行修正(详见进程平均等待时间 sleep_avg),修正的结果将在下一次调度时体现。 d) 进程因时间片相关的原因被剥夺 cpu 在 schedule_tick() 中(由时钟中断启动),进程可能因两种原因被剥夺 cpu,一是时间片耗尽,一是因时间片过长而分段。这两种情况都会调用effect_prio() 重新计算优先级,重新入队。 e) 其它时机 这些其它时机包括 IDLE 进程初始化(init_idle())、负载平衡(move_task_away(),详见调度器相关的负载平衡)以及修改 nice 值(set_user_nice())、修改调度策略(setscheduler())等主动要求改变优先级的情况。 由上可见,2.6 中动态优先级的计算过程在各个进程运行过程中进行,避免了类似 2.4 系统中就绪进程很多时计算过程耗时过长,从而无法预计进程的响应时间的问题。同时,影响动态优先级的因素集中反映在 sleep_avg 变量上。 进程调度 睡眠和唤醒 DECLARE_WAITQUEUE(wait,current); add_wait_queue(q,wait); set_current_state(TASK_INTERRUPTIBLE); while (!condition) schedule(); set_current_state(TASK_RUNNING); remove_wait_queue(q,wait); 看书36页图。 进程调度 负载平衡 为SMP体系结构的硬件准备 为每个CPU单独提供锁和可执行队列 函数load_balance()在kernel/sched.c中 主要完成的是进程在处理机等待队列的迁移(37页图) 相应的代码看起来比较复杂,主要完成的步骤如下: 调用find_busiest_queue 从找到
文档评论(0)