作业调度
我们知道,磁盘上的可执行程序只有装入内存,成为进程才可以运行。在磁盘上有许多的可执行程序等待被操作系统唤入内存执行,我们把可执行程序在磁盘上的调度称之为作业调度。
注意:这种说法听起来好像是作业在磁盘上的调度而非内存中,这里是一个误区,实际上作业调度是指调度注册到内存中的JCB,然后选择一个JCB将对应的可执行程序唤入内存的过程。
作业调度和进程调度的区别:
- 作业调度也被称为长程调度,由作业调度器(各种调度算法的软件组件)来执行。
- 进程调度也被称为短程调度,由进程调度器来执行。
- 作业调度的主要目标是选择磁盘上合适的可执行程序调入内存,成为进程。
- 进程调度的主要目标是选择合适的进程在CPU上执行。
如何设计?
操作系统的管理方式:先描述,再组织。
作业控制块(JCB):在用户双击一个可执行程序时,操作系统会先为这个作业创建的描述信息。
JCB中具有:作业标识、用户名称、作业类型(CPU繁忙型/IO繁忙型)、作业状态、优先级、作业运行时间、资源需求等。
JCB创建之后,操作系统会将JCB放入后备队列中,使用作业调度器调度内存中的各个作业JCB,当某个JCB将要被调度时,操作系统将唤入对应的可执行程序,创建进程,转为进程调度。
注意:作业调度和进程调度都是在内存中进行的,只需要调度他们的控制块即可。
总结
作业调度是筛选磁盘上合适的可执行程序调入内存,进程调度是筛选内存中合适的进程放到CPU上。这两种调度相辅相成,当进程调度时发现CPU繁忙时,可以减少CPU密集型作业的调入,二者相互协调,最大的发挥出机器的性能。
我们上面大概叙述了什么是作业调度,作业调度和进程调度的区别,具体的调度策略由各种算法实现。
程序的装入和链接
程序是如何装入内存的,操作系统在中间是如何设计的呢?
程序的装入分为以下三步:
- 编译:将源代码编译形成若干组目标模块。
- 链接:将若干组目标模块和库函数链接到一起,形成装入模块。
- 装入:将装入模块装入物理内存。
具体来说,装入模块是如何装入内存的呢?
- 绝对装入方式:这种方式只适用于单道批处理系统,即内存中同时只有一个进程,此时可以将用户程序编译后产生的地址看作是物理地址直接装入对应的内存区域。
- 可重定位装入方式:在多道处理系统中,由于内存中同时会存在多个进程,如果按照绝对装入方式,物理地址是在编译期间确定的,那势必多个进程会产生内存冲突。可重定位装入方式是将每个作业根据内存的具体情况装入适当的位置(操作系统来完成)。这种方式显然就是将编译器生成的作业地址空间作为整体,偏移到内存的某块区域上,对用到地址的指令进行物理地址变换(加上偏移量)。因为这里地址变换是装入时一次性完成的,所以也叫做静态重定位。
- 动态运行时装入方式:在具有虚拟存储器的操作系统中,支持进程的对换,一个进程可能被会被来回换入换出,每次换入的位置是不确定的,不可采用静态重定位的方式。动态运行时装入指的是程序加载到内存中的合适区域后,对使用地址的指令不进行修改,而是在运行时再进行地址变换。需要使用重定位寄存器,每次装入时,将装入位置的物理首地址存入寄存器,每执行一条指令时,用到的地址为作业空间地址+物理首地址。
程序的链接
源代码在经过编译后形成的若干个目标模块后,需要将这些目标模块和库函数链接形成装入模块,链接指的是什么?如何链接呢?
链接指的是将编译形成的若干个二进制文件和库文件合并。
合并后,再修改每个模块内的相对地址,以及修改每个模块内指令使用的地址为合并后的地址。
链接方式:
- 静态链接:一次性将所有模块和库合并,形成可执行文件。
- 动态链接:将所有模块装入后,运行时需要调用外部模块,才产生链接。
下篇介绍:站在操作系统的视角,有程序要装入时,我该如何把自己的内存资源合理分配出去呢?
相关技术:内存分配方式、虚拟地址空间、页表、段表等