【操作系统】unix 进程调度策略

来源:互联网 发布:crm软件 用百会 编辑:程序博客网 时间:2024/05/20 06:51

这一周为了准备OS课程的Seminar而去研究了一下Unix的进程调度,从网上的资料和我查阅的纸质资料上看,研究System V的比较多,所以我就拿System V来做例子。

需要注意的一点是,System V第一个版本是1983年发布的,Sytem V Release 4(1988)最成功的一个版本,离现在也有点久远了,*nix各种分支进化到现在和80年代比应该发生了比较大的变化,但是它们的设计思想还是值得研究一番的。

Unix启动过程

Alt text

  • 引导程序自举
  • 引导程序完成后,系统控制权转移给Unix内核,Unix OS正式开始工作
  • 内核创建0号进程
  • 0号进程创建1号进程init,并将控制权交给init
  • init查询当前存在的终端数,为每一个终端创建一个新的管理进程
  • 管理进程等待用户登录
  • 用户登录后,系统为每一个用户启动一个shell进程
  • 用户输入命令,由shell进程创建新的进程

Unix进程上下文结构

  • proc结构:常驻内存,记录了进程的基本信息。
  • user结构:不常驻内存,在进程执行时调入内存,记录了内存的私有信息和数据。
  • 正文段:程序代码和常量,可被多个进程访问的共享区域。
  • 数据段:进程的私有信息,用户态进程访问的区域。
  • 系统栈:进程在系统态执行时完成子程序嵌套和中断处理时使用的信息保留区,只能被系统态进程使用。
  • 用户栈:进程在用户态执行时完成子程序嵌套和中断处理时使用的信息保留区。

0号进程三大任务

  • 由核心程序创建,在初始化时完成1号进程的创立
  • 在以后的管理中,负责进程的调度与分配
  • 在以后的管理中,负责进程的内外存交换

Unix进程状态转换图

Alt text

用户态和系统态的切换

Alt text
PSW:处理器状态寄存器:反映了当前执行进程的访问方式,比如进程在何种状态下执行、中断的优先级的状态是怎样的、进入中断或陷入指令之前处理器的执行方式是怎样的等等。

进程调度程序(0号进程的switch程序)

  • 对参与竞争CPU且已具备执行条件的进程进行分析和裁决
  • 对选中的进程做处理器控制权移交
  • 管理进程运行中各种状态的转换
  • 完成进程在系统内外存之间的交换

调度算法

动态优先级多级反馈循环调度法(Round Robin With Multilevel Feedback)

  1. 当一个时间片结束时,系统为所有进程计算优先级
  2. 计算后查看是否有优先级高于当前进程且处于“内存就绪”的进程,将它们选出
  3. 将选出的进程设置调度标志
  4. 下一轮调度开始时,调度已设置了高优先级调度标志且优先级最高的进程,让其在处理器中开始运行

优先数计算

Unix是根据优先数来判断进程调度优先级的。
优先数是进程的proc结构中的char p_pri字段,值的范围是0-127,优先数越小,优先级越高。
0-49之间的优先数是系统态进程的优先级,用户态下的进程优先级为50-127之间。

计算公式

p_pri = p_cpu / 2 + PUSER + p_nice + NZERO

  • PUSER和NZERO是基本用户优先数的阈值,是系统预设的,分别是25和20
  • p_cpu表示该进程最近一次占用CPU的时间,对于当前进程,每个时钟中断(注意不是每个时间片)该值加1(最大值80)。若时钟中断周期是16.6ms,则一秒内右60个时钟中断
  • 新创建进程的p_cpu为0
  • p_nice是用户可以通过系统调用设置的一个优先级偏移值,默认为20。超级用户可以设置其在0到39之间,而普通用户只能增大该值

一个时间片结束后,系统将每个进程的p_cpu除以2,这个过程称为衰减。
衰减过后,系统重新计算每个进程的p_pri

分析一下这条公式,系统运行时PUSER和NZERO是常数,而p_nice一般也是一个常数,所以进程优先数就取决于p_cpu。对于那些占用CPU较长时间的进程,其优先数在衰减后还是比那些最近占用CPU较短的进程大,所以其优先级会变小,反过来,那些不怎么占用CPU的进程的优先级会增加,所以会在下一次调度中被执行。这是一种负反馈调节。

优先数0-49是内核保留的优先数,当进程睡眠(阻塞)时,就会被赋予一个系统优先级(0-49),由于比用户优先数小,所以这些进程醒来的时候(比如IO完成)能被及时处理。

调度时机的疑问

关于调度时机,是让我比较疑惑的一点,我手上的中文教材和网上的一个课件说的都是调度时机有以下两个:

  • 第一种情况:当进程执行中自动放弃处理机时(比如等待I/O,或者运行结束),进行一次进程调度
  • 第二种情况:当进程由系统态转入用户态时,系统安排一次调度,这样做的意图是使那些被设置了高优先级调度标志,并且在内存中就绪的进程可以有机会抢先进入执行状态

然而在查到的外文资料里没有提到“调度时机”。

如果是以上两个调度时机,那么说明在时间片结束的时候可能没有调度发生,因为只是发生了优先数计算,那么假设有一个用户态进程在执行过程中进行了大量计算(或者死循环),既没有主动放弃处理机,也没有从系统态到用户态的转换,那么处理机就一直被它占用。

0号进程一直是系统态,如果0号进程在时间片结束、计算完优先数并设置标记以后,让之前的用户进程继续执行,是否算是一种“系统态到用户态的转换”?如果是,那么就出现了调度时机,这种时机的安排就是有效的。

虽然有这个疑问,不过调度的主要思想我已经理解,也许后面的学习中这些疑问都会被解决。

参考资料

  • http://vega.cs.kent.edu/~mikhail/classes/os.s99/l8advancedscheduling.PDF
  • http://ettc.sysu.edu.cn/2005wlkc/caozuoxitong/book/chapter5/lesson3/lesson3.1.htm
  • 张红光,李福才《UNIX操作系统教程》,机械工业出版社

原文链接:http://blog.dyzeng.org/2016/03/17/Unix-scheduling/

原创粉丝点击