第8章UNIX操作系统 UNIX操作系统从一个非常简单的操作系统发展成为性能先进、功能强大、使用广泛的操 作系统,并成为事实上的多用户、多任务操作系统标准。 8.1内容辅导 8.1.1UNIX操作系统概述 1.UN1X系统的特点 NIX系统的特点如下: (1)UNIX是一个多用户、多任务的操作系统,每个用户都可同时执行多个进程,系统中 的进程数目在逻辑上不受限制。 (2)提供了精选的、丰富的系统功能,其中许多功能在实现思想上有其独到之处,且是高 效的。 (3)该系统用高级语言编写,使系统具有易读、易懂、易修改、易移植等一系列优点, 且系绕代码十分紧凑 (4)提供了良好的用户界面。该系统提供一种命令程序设计语言 SHELL作为用户界面 同时提供了系统调用作为用户程序与系统的接口。这些界面既能为用户提供各种服务,又相当 简洁。 (5)在UNIX系统中使用了树型结构的文件系统,它具有良好的安全性、保密性和可维护 性,在文件系统的实现方法上,也有较多创新。 (6)系统提供了多种通信机制,以满足各种进程通信的需要。 ⑦)在存储管理上,为提高内存利用率,提供了进程对换存储管理方式和请求调页的存储 管理方式,以实现虚拟存储器 2.UNX系统核心体系结构 整个UNIX系统可分成两大部分。第一部分是由用户程序和系统提供的服务构成的所谓核 外程序,形成了良好的系统环境:第二部分是操作系统,又称为核心,其中两个最主要的部分是 文件子系统和进程控制子系统。 用户程序可以通过高级语言的程序库或低级语言的直接系统调用进入核心。核心中的进 程控制子系统负责进程同步、进程间通信、进程调度和存储管理。文件子系统管理文件,包括 分配文件存储空间、控制对文件的存取以及为用户检索数据。文件子系统通过一个缓冲机制 同设备驱动部分交互作用。设备管理、进程管理及存储管理通过硬件控制接口与硬件交互作 用 8.1.2UNIX的进程 在INIX系统中,采用了段页式存储管理《在UNIX中将段称为区〉方式,因此一个进程实 体由若干个区组成,包括程序区、数据区、核区等。每个区又可分为若干页 1.进程的描述 在 UNIX System V中,将PCB分成进程表项和U区。除进程表项和U区外,管理进程的数 据结构还有本进程区表和系统区表 (1)进程表项 进程表项中的每个表目主要包含以下信息:标识进程状态的状态域:用户标识号,简称 UID或用户⑩D:进程标识号,简称PI或进程P:存储区位置和长度:调度参数(包括优先数 等);软中断信号域;各种计时域:指向U区的指针:事件描述域
第 8 章 UNIX 操作系统 UNIX 操作系统从一个非常简单的操作系统发展成为性能先进、功能强大、使用广泛的操 作系统,并成为事实上的多用户、多任务操作系统标准。 8.1 内容辅导 8.1.1 UNIX 操作系统概述 1.UNlX 系统的特点 UNIX 系统的特点如下: (1)UNIX 是一个多用户、多任务的操作系统,每个用户都可同时执行多个进程,系统中 的进程数目在逻辑上不受限制。 (2)提供了精选的、丰富的系统功能,其中许多功能在实现思想上有其独到之处,且是高 效的。 (3)该系统用高级语言编写,使系统具有易读、易懂、易修改、易移植等一系列优点, 且系绕代码十分紧凑。 (4)提供了良好的用户界面。该系统提供一种命令程序设计语言 SHELL 作为用户界面; 同时提供了系统调用作为用户程序与系统的接口。这些界面既能为用户提供各种服务,又相当 简洁。 (5)在 UNIX 系统中使用了树型结构的文件系统,它具有良好的安全性、保密性和可维护 性,在文件系统的实现方法上,也有较多创新。 (6)系统提供了多种通信机制,以满足各种进程通信的需要。 (7)在存储管理上,为提高内存利用率,提供了进程对换存储管理方式和请求调页的存储 管理方式,以实现虚拟存储器。 2.UNlX 系统核心体系结构 整个 UNIX 系统可分成两大部分。第一部分是由用户程序和系统提供的服务构成的所谓核 外程序,形成了良好的系统环境:第二部分是操作系统,又称为核心,其中两个最主要的部分是 文件子系统和进程控制子系统。 用户程序可以通过高级语言的程序库或低级语言的直接系统调用进入核心。核心中的进 程控制子系统负责进程同步、进程间通信、进程调度和存储管理。文件子系统管理文件,包括 分配文件存储空间、控制对文件的存取以及为用户检索数据。文件子系统通过一个缓冲机制 同设备驱动部分交互作用。设备管理、进程管理及存储管理通过硬件控制接口与硬件交互作 用。 8.1.2 UNIX 的进程 在 UNIX 系统中,采用了段页式存储管理〈在 UNIX 中将段称为区〉方式,因此一个进程实 体由若干个区组成,包括程序区、数据区、核区等。每个区又可分为若干页。 1.进程的描述 在 UNIX System V 中,将 PCB 分成进程表项和 U 区。除进程表项和 U 区外,管理进程的数 据结构还有本进程区表和系统区表。 (1)进程表项 进程表项中的每个表目主要包含以下信息:标识进程状态的状态域;用户标识号,简称 UID 或用户 ID;进程标识号,简称 PID 或进程 P;存储区位置和长度;调度参数(包括优先数 等);软中断信号域;各种计时域;指向 U 区的指针;事件描述域
(2)U区 U区中的各个域进一步刻画了进程的特性,U区主要包含以下信息:指向进程表项的指针:真 正用户标识符( real user ID)及有效用户标识符( effective user ID):用户文件描述符表 当前目录和当前根:计时器域:一些输入/输出参数;限制域;出错域:返回值域:信号处理 数组。 (3)系统区表 UNIX System V把一个进程的虚地址空间划分为若干连续的逻辑区,有正文区、数据区 核区等。这些区是可被共享和保护的独立实体,多个进程可以共享一个区。为了对区进行管理, 在核心中设置了一个系统区表(简称区表),各表项中记录了描述活动区的有关信息:区的类型 和大小:区的状态(一个区具有这样几种状态:锁住、在请求中、在装入过程中、有效):区 在物理存储器中的位置;引用计数:指向文件索引节点的指针 (4)本进程区表 为了记录进程的每个区在进程中的虚地址,并通过它找到该区在物理存储器中的实地址, 系统为每个进程配置了一张进程区表,表中每一项记录一个区的起始虚地址及指向系统区表 中对应区表项的指针。这样,核心通过查找本进程区表和系统区表,便可将区的逻辑地址变换 为物理地址。这里使用两张表来对区地址进行映像是为了便于实现区的共享。 2.进程状态及其转换 在 UNIX System V中,为进程设置了9种状态: (1)创建状态:进程刚被创建时,进程已经存在,但尚未完全获得运行所必须具有的资源 因此它既不是就绪状态,也不是睡眠状态。这个状态可被认为是进程的初始状态。 (2)内存中就绪:进程己在内存中且处于就绪状态。对于新创建的进程,若系统有足够的 内存,核心便将它装入内存,从而使新进程转入内存中就绪状态 (3)就绪且换出:进程处于就绪状态,但被换出到外存中。在创建新进程时,若无足够的 内存,核心便将新进程安置在外存对换区中,并赋予就绪且换出状态。此外,原已在内存中的进 程,可能因内存紧张而被换出,同样也成为就绪且换出状态 (4)核心态执行:进程在核心态下执行。 (5)用户态执行:进程在用户态下执行 (6)内存中睡眠进程已在内存中且正处于睡眠状态。例如,进程所执行的系统调用涉及 到I/0操作,而进程又须等待U0操作的完成,则进程将进入内存中睡眠 (7)睡眠且换出当内存紧张时,在内存中睡眠的进程,首先被核心换出到外存上,以腾出 内存。此时,进程将变为睡眠且换出状态。 (⑧)被剥夺状态当进程从核心态返回用户态时,核心剥夺了该进程的处理机,使该进程处 于被剥夺状态。 (9)僵死状态进程执行了exit系统调用后,便处于僵死状态。此时,进程已不存在,但它 留下一些含有状态码和一些计时统计信息的记录,供父进程收集 3.进程上下文 当一个进程在执行时,可看作是在它的进程上下文中执行。一个进程的上下文〈 context 由三部分组成:用户级上下文、寄存器上下文和系统级上下文。 (1)用户级上下文:用户级上下文是由进程虚地址空间中的正文、数据、用户校和共享 存储区组成。在采用对换和请求调页存储管理方式时,只有进程的部分虚地址空间驻留在内 存。但无论它是否驻留在内存,都属于用户级上下文的组成部分 (2)寄存器上下文:寄存器上下文主要由CPU中的一些寄存器内容构成。主要的寄存器有 程序寄存器:处理机状态寄存器:栈指针;通用寄存器 (3)系统级上下文:系统级上下文可分为静态和动态两部分
(2)U 区 U 区中的各个域进一步刻画了进程的特性,U 区主要包含以下信息:指向进程表项的指针;真 正用户标识符(real user ID)及有效用户标识符(effective user ID);用户文件描述符表; 当前目录和当前根;计时器域;一些输入/输出参数;限制域;出错域;返回值域;信号处理 数组。 (3)系统区表 UNIX System V 把一个进程的虚地址空间划分为若干连续的逻辑区,有正文区、数据区、 核区等。这些区是可被共享和保护的独立实体,多个进程可以共享一个区。为了对区进行管理, 在核心中设置了一个系统区表(简称区表),各表项中记录了描述活动区的有关信息:区的类型 和大小;区的状态(一个区具有这样几种状态:锁住、在请求中、在装入过程中、有效);区 在物理存储器中的位置;引用计数;指向文件索引节点的指针。 (4)本进程区表 为了记录进程的每个区在进程中的虚地址,并通过它找到该区在物理存储器中的实地址, 系统为每个进程配置了一张进程区表,表中每一项记录一个区的起始虚地址及指向系统区表 中对应区表项的指针。这样,核心通过查找本进程区表和系统区表,便可将区的逻辑地址变换 为物理地址。这里使用两张表来对区地址进行映像是为了便于实现区的共享。 2.进程状态及其转换 在 UNIX System V 中,为进程设置了 9 种状态: (1)创建状态:进程刚被创建时,进程已经存在,但尚未完全获得运行所必须具有的资源, 因此它既不是就绪状态,也不是睡眠状态。这个状态可被认为是进程的初始状态。 (2)内存中就绪:进程己在内存中且处于就绪状态。对于新创建的进程,若系统有足够的 内存,核心便将它装入内存,从而使新进程转入内存中就绪状态。 (3)就绪且换出:进程处于就绪状态,但被换出到外存中。在创建新进程时,若无足够的 内存,核心便将新进程安置在外存对换区中,并赋予就绪且换出状态。此外,原已在内存中的进 程,可能因内存紧张而被换出,同样也成为就绪且换出状态。 (4)核心态执行:进程在核心态下执行。 (5)用户态执行:进程在用户态下执行。 (6)内存中睡眠进程已在内存中且正处于睡眠状态。例如,进程所执行的系统调用涉及 到 I/O 操作,而进程又须等待 UO 操作的完成,则进程将进入内存中睡眠。 (7)睡眠且换出当内存紧张时,在内存中睡眠的进程,首先被核心换出到外存上,以腾出 内存。此时,进程将变为睡眠且换出状态。 (8)被剥夺状态当进程从核心态返回用户态时,核心剥夺了该进程的处理机,使该进程处 于被剥夺状态。 (9)僵死状态进程执行了 exit 系统调用后,便处于僵死状态。此时,进程已不存在,但它 留下一些含有状态码和一些计时统计信息的记录,供父进程收集。 3. 进程上下文 当一个进程在执行时,可看作是在它的进程上下文中执行。一个进程的上下文〈context〉 由三部分组成:用户级上下文、寄存器上下文和系统级上下文。 (1)用户级上下文:用户级上下文是由进程虚地址空间中的正文、数据、用户校和共享 存储区组成。在采用对换和请求调页存储管理方式时,只有进程的部分虚地址空间驻留在内 存。但无论它是否驻留在内存,都属于用户级上下文的组成部分。 (2)寄存器上下文:寄存器上下文主要由 CPU 中的一些寄存器内容构成。主要的寄存器有: 程序寄存器;处理机状态寄存器;栈指针;通用寄存器。 (3)系统级上下文:系统级上下文可分为静态和动态两部分:
①静态部分:在进程的整个生命期中,系统级上下文的静态部分只有一个,其大小保持不 变,它由三部分组成:进程表项、U区和本进程区表项、系统区表项和页表 ②动态部分:在进程的整个生命期中,系统级上下文动态部分的数目是可变的。它包括 核心钱和若干层寄存器上下文。 4.进程控制 在 UNIX System V中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基 本单位。为了对进程进行控制,UNIX提供了一系列系统功能调用,用户可以利用它们来实现 创建一个进程"或"终止一个进程的执行”等功能。 用于对进程实施控制的主要系统调用有: (1)系统调用fork 在UNIX系统中,除了0进程外,其他所有进程都是被另一个进程利用fork创建的。0进 程是一个特殊的系统进程,它在系统引导时被创建的。系统初启时,0进程又创建1进程,此 后0进程就变为对换进程,而1进程就变为系统的始祖进程。UNIX利用fork为每个终端创建 个子进为用户服务,如等待用户登录、执行 shell命令执行程序等。此后,每个终端子进程 又可利用fork来创建它的子进程,从而可形成一棵进程树 (2)系统调用exec fork系统调用只是将父进程的上下文复制到新进程中,因此执行完fork时,父子进程具 有完全相同的正文区、数据区及用户校区。若要使新进程执行的程序不同于父进程,可以使用 exec系列系统功能调用。exec系列中的系统调用都完成同样的功能,它们把一个新的程序装 入调用进程的内存空间,以改变调用进程的执行代码,从而使调用进程执行新引入的程序功 能。如果exec调用成功,调用进程将被覆盖,然后从新引入程序的入口开始执行。这就产生了 个新进程,它的进程标识符与调用进程相同,但所执行的程序代码不同。这就是说,exec没 有建立一个与调用进程并发执行的新进程,而是用新进程取代了老进程。这一组系统调用的主 要差别在于给出参数的数目和形式不同,给出参数的形式有两种,一种是直接给出指向每个参 数的指针,另一种是给出指向参数表的指针。 (3)系统调用exit 对于一般的用户进程,在其任务完成后应尽快撤消。为了及时回收进程所占用的资源并减少父 进程的干预,UNIX系统利用exit来实现进程的自我终止。通常,父进程在创建子进程时,应在 子进程的末尾安排一条exit,使子进程自我终止。 (4)系统调用wait 系统调用wait用于将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为 止。如果在wait调用前,已有子进程暂停或终止,则调用进程作适当处理后便返回。 5.进程调度 UNIX系统是单纯的分时系统,因而未设置作业调度。对进程的调度采用多级反馈队列轮 转调度方式。相应地,在系统中便为就绪进程设置了多个就绪队列。调度程序在进行调度时, 总是先从最高优先级队列中取出排在队列最前面的进程。仅当最高优先级队列中没有进程时, 才从次高优先级队列中找出其队首进程,令它执行一个时间片后,又剥夺该进程的执行,然后 再从优先级最高的队列中取出下一个就绪进程投入运行 (1)进程优先级的分类 在UNIX系统中,进程的优先级分为两类:核心优先级(又分为可中断和不可中断两类优先 级)和用户优先级(又可分成n+1级,其中第0级为最高优先级,第n级的优先级最低)。 (2)优先级的计算 UNIX SystemⅤ中的用户优先级是可变的,它随着占用CPU时间的增加而降低。核心每隔1 秒钟便根据一个衰减函数来调整每个进程的最近CPU使用时间,并按下述公式对各进程重新
①静态部分:在进程的整个生命期中,系统级上下文的静态部分只有一个,其大小保持不 变,它由三部分组成:进程表项、U 区和本进程区表项、系统区表项和页表。 ②动态部分:在进程的整个生命期中,系统级上下文动态部分的数目是可变的。它包括: 核心钱和若干层寄存器上下文。 4. 进程控制 在 UNIX System V 中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基 本单位。为了对进程进行控制,UNIX 提供了一系列系统功能调用,用户可以利用它们来实现 "创建一个进程"或"终止一个进程的执行"等功能。 用于对进程实施控制的主要系统调用有: (1)系统调用 fork 在 UNIX 系统中,除了 0 进程外,其他所有进程都是被另一个进程利用 fork 创建的。0 进 程是一个特殊的系统进程,它在系统引导时被创建的。系统初启时,0 进程又创建 1 进程,此 后 0 进程就变为对换进程,而 1 进程就变为系统的始祖进程。UNIX 利用 fork 为每个终端创建 一个子进为用户服务,如等待用户登录、执行 shell 命令执行程序等。此后,每个终端子进程 又可利用 fork 来创建它的子进程,从而可形成一棵进程树。 (2)系统调用 exec fork 系统调用只是将父进程的上下文复制到新进程中,因此执行完 fork 时,父子进程具 有完全相同的正文区、数据区及用户校区。若要使新进程执行的程序不同于父进程,可以使用 exec 系列系统功能调用。exec 系列中的系统调用都完成同样的功能,它们把一个新的程序装 入调用进程的内存空间,以改变调用进程的执行代码,从而使调用进程执行新引入的程序功 能。如果 exec 调用成功,调用进程将被覆盖,然后从新引入程序的入口开始执行。这就产生了 一个新进程,它的进程标识符与调用进程相同,但所执行的程序代码不同。这就是说,exec 没 有建立一个与调用进程并发执行的新进程,而是用新进程取代了老进程。这一组系统调用的主 要差别在于给出参数的数目和形式不同,给出参数的形式有两种,一种是直接给出指向每个参 数的指针,另一种是给出指向参数表的指针。 (3)系统调用 exit 对于一般的用户进程,在其任务完成后应尽快撤消。为了及时回收进程所占用的资源并减少父 进程的干预,UNIX 系统利用 exit 来实现进程的自我终止。通常,父进程在创建子进程时,应在 子进程的末尾安排一条 exit,使子进程自我终止。 (4)系统调用 wait 系统调用 wait 用于将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为 止。如果在 wait 调用前,已有子进程暂停或终止,则调用进程作适当处理后便返回。 5.进程调度 UNIX 系统是单纯的分时系统,因而未设置作业调度。对进程的调度采用多级反馈队列轮 转调度方式。相应地,在系统中便为就绪进程设置了多个就绪队列。调度程序在进行调度时, 总是先从最高优先级队列中取出排在队列最前面的进程。仅当最高优先级队列中没有进程时, 才从次高优先级队列中找出其队首进程,令它执行一个时间片后,又剥夺该进程的执行,然后, 再从优先级最高的队列中取出下一个就绪进程投入运行。 (1)进程优先级的分类 在 UNIX 系统中,进程的优先级分为两类:核心优先级(又分为可中断和不可中断两类优先 级)和用户优先级(又可分成 n+1 级,其中第 0 级为最高优先级,第 n 级的优先级最低)。 (2)优先级的计算 UNIX System V 中的用户优先级是可变的,它随着占用 CPU 时间的增加而降低。核心每隔 1 秒钟便根据一个衰减函数来调整每个进程的最近 CPU 使用时间,并按下述公式对各进程重新
计算其用户优先数(优先数越大,优先级越低:优先数越小,优先级越高)。 decay( CPU)=CPU/2 优先数=最近使用CP的时间/2+基本用户优先数 核心首先从处于内存就绪"或"被剥夺”状态的进程中选择一个优先级最高的进程。若系 统中同时有多个进程都具有最高优先级,则核心将选择其中处于就绪状态最久的进程,将它从 所在队列中移出,恢复其上下文,使之执行。 (3)进程切换 在操作系统中,凡是要进行中断处理和系统调用时,都将涉及到进程上下文的保存和恢复 此时系统所保存和恢复的是同属于一个进程的上下文。而在进程调度之后实现进程则是另 个进程的上下文,这一进程取决于调度程序所选中的是哪一个进程。 ①进程上下文的保存与恢复 不论发生了哪种中断(如I/0设备中断、程序中断〉,如果处理机运行级低于该中断的级别 则处理机将响应该中断,并提高处理机的运行级,以屏蔽其他中断。 ②进程上下文的切换 总的说来,引起进程上下文切换的原因,都是由于核心进行了进程调度而选中了一个新的 进程运行。在NIX系统中,由于采用了可剥夺的调度方式,因而引起进程调度的原因有时间片 完、当前进程执行了 sleep例程、进程执行完等,它们都会导致进程上下文的切换。 6.进程的同步与通信 在 UNIX SyStem V中,进程的同步与通信提供了软中断信号和管道机制以及新的进程通 信机构,简称IPC( Interprocess Comnmication)。它由三部分组成:消息机制、共享存储器机 制和信号量机制 (1)软中断信号:软中断信号(简称信号)是一种实现进程间简单通信的设施,用于通知 对方发生了异常事件。UNIX系统V中,共有19个软中断信号。软中断是对硬件中断的一种模 拟,发送软中断就是向接收进程的进程表项结构中的相应项发送一个软中断信号。如果用户进 程发送的软中断信号大于19,则接收进程不予理睬,从而发送无效。接收进程在收到软中断信 号后,将按照事先的规定去执行一个软中断处理程序。但是软中断处理程序不像硬件中断处理 程序那样,收到中断信号后立即被启动,它必须等到接收进程执行时才能生效。另外,一个进程 自己也可以向自己发送软中断信号,以便在某些意外的情况下,进程能转入规定好的处理程 序 (2)管道:用信号来处理异常事件或错误是非常合适的,但用它来处理进程之间的大量信 息传送就显得非常不适宜。为此,UNIX又提供了一种称作管道的机构。所谓管道是指能连接 某些读进程和写进程的、专门用于进程通信的共享文件(又称pipe文件)。它允许读/写进程 按先进先出的方式传送数据,即写进程从管道的一端向管道写入数据流,读进程从管道的另 端读出数据流。管道的类型有无名管道和有名管道,进程可利用pipe系统调用来建立一个无 名管道:对无名管道的读写涉及到对pipe文件大小的限制:进程互斥;进程写管道和进程读 管道 3)消息:消息是一个格式化的可变长的信息单元。消息机制允许由一个进程给其他任 何进程发送一个消息。当一个进程收到多个消息时,可将它们排成一个消息队列。在UNIX中 消息机制向用户提供了四个系统调用,分别用于建立、发送和接收消息等。 消息有消息首部和消息队列头标,在UNIX系统中,每一个消息队列都有一个称为关键字 ey)的名字,关键字是由用户指定的。此外,消息队列还有一消息队列描述符,其作用与用户 文件描述符一样,也是为了方便用户和系统对消息队列的访问。进程可利用系统调用 meget 来建立一消息队列,或者获取一消息队列的描述符:用 msgsnd()系统调用向指定的消息队列 发送一个消息,并将发送消息链接到该消息队列的尾部;用 msgrcv(系统调用从指定的消息
计算其用户优先数(优先数越大,优先级越低:优先数越小,优先级越高)。 decay(CPU)=CPU/2 优先数=最近使用 CPU 的时间/2+基本用户优先数 核心首先从处于"内存就绪"或"被剥夺"状态的进程中选择一个优先级最高的进程。若系 统中同时有多个进程都具有最高优先级,则核心将选择其中处于就绪状态最久的进程,将它从 所在队列中移出,恢复其上下文,使之执行。 (3)进程切换 在操作系统中,凡是要进行中断处理和系统调用时,都将涉及到进程上下文的保存和恢复, 此时系统所保存和恢复的是同属于一个进程的上下文。而在进程调度之后实现进程则是另一 个进程的上下文,这一进程取决于调度程序所选中的是哪一个进程。 ①进程上下文的保存与恢复 不论发生了哪种中断(如 I/0 设备中断、程序中断〉,如果处理机运行级低于该中断的级别, 则处理机将响应该中断,并提高处理机的运行级,以屏蔽其他中断。 ②进程上下文的切换 总的说来,引起进程上下文切换的原因,都是由于核心进行了进程调度而选中了一个新的 进程运行。在 UNIX 系统中,由于采用了可剥夺的调度方式,因而引起进程调度的原因有时间片 完、当前进程执行了 sleep 例程、进程执行完等,它们都会导致进程上下文的切换。 6.进程的同步与通信 在 UNIX System V 中, 进程的同步与通信提供了软中断信号和管道机制以及新的进程通 信机构,简称 IPC(Interprocess Comnmication)。它由三部分组成:消息机制、共享存储器机 制和信号量机制。 (1)软中断信号:软中断信号(简称信号)是一种实现进程间简单通信的设施,用于通知 对方发生了异常事件。UNIX 系统 V 中,共有 19 个软中断信号。软中断是对硬件中断的一种模 拟,发送软中断就是向接收进程的进程表项结构中的相应项发送一个软中断信号。如果用户进 程发送的软中断信号大于 19,则接收进程不予理睬,从而发送无效。接收进程在收到软中断信 号后,将按照事先的规定去执行一个软中断处理程序。但是软中断处理程序不像硬件中断处理 程序那样,收到中断信号后立即被启动,它必须等到接收进程执行时才能生效。另外,一个进程 自己也可以向自己发送软中断信号,以便在某些意外的情况下,进程能转入规定好的处理程 序。 (2)管道:用信号来处理异常事件或错误是非常合适的,但用它来处理进程之间的大量信 息传送就显得非常不适宜。为此,UNIX 又提供了一种称作管道的机构。所谓管道是指能连接 某些读进程和写进程的、专门用于进程通信的共享文件(又称 pipe 文件〉。它允许读/写进程 按先进先出的方式传送数据,即写进程从管道的一端向管道写入数据流,读进程从管道的另一 端读出数据流。管道的类型有无名管道和有名管道,进程可利用 pipe 系统调用来建立一个无 名管道;对无名管道的读写涉及到对 pipe 文件大小的限制;进程互斥;进程写管道和进程读 管道。 (3)消息:消息是一个格式化的可变长的信息单元。消息机制允许由一个进程给其他任 何进程发送一个消息。当一个进程收到多个消息时,可将它们排成一个消息队列。在 UNIX 中, 消息机制向用户提供了四个系统调用,分别用于建立、发送和接收消息等。 消息有消息首部和消息队列头标,在 UNIX 系统中,每一个消息队列都有一个称为关键字 (key)的名字,关键字是由用户指定的。此外,消息队列还有一消息队列描述符,其作用与用户 文件描述符一样,也是为了方便用户和系统对消息队列的访问。进程可利用系统调用 msgget 来建立一消息队列,或者获取一消息队列的描述符;用 msgsnd( )系统调用向指定的消息队列 发送一个消息,并将发送消息链接到该消息队列的尾部;用 msgrcv()系统调用从指定的消息
队列中接收指定类型的消息;用户在建立了消息队列后,可利用 nsgct系统调用来读取它的 状态信息并进行修改,如査询消息队列描述符、修改消息队列的许可权等。 (4)共享存储区:共享存储区是UNⅨX系统中通信速度最高的一种通信机制。该机制可使 若干进程共享主存中的某一个区域,且使该区域出现在多个进程的虚地址空间中。另一方面, 个进程的虚地址空间中又可连接多个共享存储区,每个共享存储区都有自己的名字。当进程 间欲利用共享存储区进行通信时,须首先在主存中建立一共享存储区,然后将它附接到自己的 虚地址空间上。此后,进程对该区的访问操作,与对其虚地址空间的其他部分的操作完全相同 进程之间以后便可通过对共享存储区中数据的读/写来进行直接通信。当用户需要使用该机制 时,必须自己设置这种设施,才能保证实现正确的通信。 当进程要利用共享存储区进行通信时,应先利用系统调用 shmget建立一共享存储区。如 果该共享存储区已由其他进程建立,则返回其描述符 shmi:进程在建立了一共享存储区并获 得了其描述符后,还须利用系统调用 shmat(将共享存储区附接到进程的虚地址空间上。此后 共享存储区便成为进程虚地址空间的一部分。进程可采用与其他虚地址空间一样的存取方法 来存取它。当进程不再需要共享存储区时,应利用系统调用 shmdt o将共享存储区与进程断 接:如同消息机制一样,可以用 sheet10系统调用对共享存储区的状态信息进行读取和修改。 当所有进程都与共享存储区断接时,便可删除该共享存储区 (5)信号量 NIX System V中采用的是信号量集机制,即由一组信号量构成的信号量集。传统的信号 量机制是对信号量施加P和V操作,而 System V中是利用 semop o系统调用来对指定信号量 进行操作。 用户可利用系统调用 semget0来建立信号量集;一旦信号量集被创建成功,便可利用 semop o系统调用对这组信号量进行操作。 8.1.3存储器管理 在早期的UNX系统中,为提高内存的利用率,己提供了内存与外存之间的进程对换机制 在 UNIX SystemⅤ中,除保留了对换功能外,还支持请求调页的存储管理方式,内存空间的分配 与回收均以页为单位进行。每个页面的大小随版本不同而异,一般在512B-4KB之间。 1.请求调页管理的数据结构 在UNIX系统中,为实现请求调页,核心配置了四种数据结构 (1)页表: UNIX SyStem V将进程的每个区分为若干页,以将它们分配到不相邻的物理块 中,为此每个区设置了一张页表。为了支持请求调页,每个页表项中需包含以下字段:物理块 号、年龄位、访问位、修改位、有效位、写时拷贝位和保护位 (2)磁盘块描述表:在UNIX系统中,每个页表项对应一个磁盘块描述项,其中记录了各页 面的磁盘拷贝所在的磁盘块号。一个页面的内容或在一个对换设备的特定块中,或在一个可执 行文件中。如果该页在一个可执行文件中,此时磁盘块描述项中的存储器类型为File,设备块 号是该页在文件中的逻辑块号。如果该页面在对换设备上,则此时的存储器类型为Disk,对换 设备号和块号则用于指示该页面的拷贝所驻留的逻辑对换设备和相应的盘块号 (3)页面数据表:每个页面数据表项描述内存中的一个物理页,每个表项包含:页状态、 内存引用计数、逻辑设备和指向空闲页链表中下一个页面数据表项的指针和指向散列队列中 下一个页面数据表项的指针。 在系统初启时,核心将所有的页面数据表项链接为一个空闲页链表,形成空闲页缓冲池。 为给一个区分配一个物理页,核心从空闲链表之首摘下一个空闲页表项,修改其对换设备号和 块号后,将它放到相应的散列队列中 (4)对换使用表:对换设备上的每一页都占有对换使用表的一个表项,表项中含有一个引 用计数,其数值表示有多少页表项指向该页
队列中接收指定类型的消息;用户在建立了消息队列后,可利用 msgctl 系统调用来读取它的 状态信息并进行修改,如查询消息队列描述符、修改消息队列的许可权等。 (4)共享存储区:共享存储区是 UNIX 系统中通信速度最高的一种通信机制。该机制可使 若干进程共享主存中的某一个区域,且使该区域出现在多个进程的虚地址空间中。另一方面, 一个进程的虚地址空间中又可连接多个共享存储区,每个共享存储区都有自己的名字。当进程 间欲利用共享存储区进行通信时,须首先在主存中建立一共享存储区,然后将它附接到自己的 虚地址空间上。此后,进程对该区的访问操作,与对其虚地址空间的其他部分的操作完全相同。 进程之间以后便可通过对共享存储区中数据的读/写来进行直接通信。当用户需要使用该机制 时,必须自己设置这种设施,才能保证实现正确的通信。 当进程要利用共享存储区进行通信时,应先利用系统调用 shmget 建立一共享存储区。如 果该共享存储区已由其他进程建立,则返回其描述符 shmid;进程在建立了一共享存储区并获 得了其描述符后,还须利用系统调用 shmat()将共享存储区附接到进程的虚地址空间上。此后, 共享存储区便成为进程虚地址空间的一部分。进程可采用与其他虚地址空间一样的存取方法 来存取它。当进程不再需要共享存储区时,应利用系统调用 shmdt()将共享存储区与进程断 接;如同消息机制一样,可以用 shmctl()系统调用对共享存储区的状态信息进行读取和修改。 当所有进程都与共享存储区断接时,便可删除该共享存储区。 (5)信号量 UNIX System V 中采用的是信号量集机制,即由一组信号量构成的信号量集。传统的信号 量机制是对信号量施加 P 和 V 操作,而 System V 中是利用 semop()系统调用来对指定信号量 进行操作。 用户可利用系统调用 semget()来建立信号量集;一旦信号量集被创建成功,便可利用 semop()系统调用对这组信号量进行操作。 8.1.3 存储器管理 在早期的 UNIX 系统中,为提高内存的利用率,己提供了内存与外存之间的进程对换机制。 在 UNIX System V 中,除保留了对换功能外,还支持请求调页的存储管理方式,内存空间的分配 与回收均以页为单位进行。每个页面的大小随版本不同而异,一般在 512B-4KB 之间。 1.请求调页管理的数据结构 在 UNIX 系统中,为实现请求调页,核心配置了四种数据结构: (1)页表:UNIX System V 将进程的每个区分为若干页,以将它们分配到不相邻的物理块 中,为此每个区设置了一张页表。为了支持请求调页,每个页表项中需包含以下字段:物理块 号、年龄位、访问位、修改位、有效位、写时拷贝位和保护位。 (2)磁盘块描述表:在 UNIX 系统中,每个页表项对应一个磁盘块描述项,其中记录了各页 面的磁盘拷贝所在的磁盘块号。一个页面的内容或在一个对换设备的特定块中,或在一个可执 行文件中。如果该页在一个可执行文件中,此时磁盘块描述项中的存储器类型为 File,设备块 号是该页在文件中的逻辑块号。如果该页面在对换设备上,则此时的存储器类型为 Disk,对换 设备号和块号则用于指示该页面的拷贝所驻留的逻辑对换设备和相应的盘块号。 (3)页面数据表:每个页面数据表项描述内存中的一个物理页,每个表项包含:页状态、 内存引用计数、逻辑设备和指向空闲页链表中下一个页面数据表项的指针和指向散列队列中 下一个页面数据表项的指针。 在系统初启时,核心将所有的页面数据表项链接为一个空闲页链表,形成空闲页缓冲池。 为给一个区分配一个物理页,核心从空闲链表之首摘下一个空闲页表项,修改其对换设备号和 块号后,将它放到相应的散列队列中。 (4)对换使用表:对换设备上的每一页都占有对换使用表的一个表项,表项中含有一个引 用计数,其数值表示有多少页表项指向该页
2.偷页进程 在UNIX系统的核心中,专门设置了一个偷页进程( page stealer),其主要任务有 每隔一定时间增加内存中所有有效页的年龄:当有效页的年龄达到规定值后便将它换出。 (1)增加有效页年龄:一个页可计数的最大年龄取决于它的硬件设施。若只设置了两位 作为年龄域,其有效页的年龄只能取值0、1、2和3。当该页的年龄为0、1、2时,该页处于 不可换出状态;而当其年龄达到3时,便可将它换出内存。每当内存中的空闲页面数低于某规 定的低限时,核心便唤醒偷页进程,由偷页进程去检查内存中的每一个活动的非上锁区,对所 有有效页的年龄字段加1。对于那些年龄字段已增至3的页便不再加1,而是将它们换出。每 当有进程访问了某个页面时,便将该页的年龄置0 (2)对换出页的几种处理方法:当偷页进程从内存中的有效页中找到可被换出的页后, 可采取下面三种方法对它们进行处理 ①若在对换设备上己有被换出页的拷贝,且被换出页的内容未被修改,则此时核心不必将 该页重写回对换设备上,而只需将该页的页表项的有效位清零,并将页面数据表项中的引用数 减1,最后将该页表项放入空闲页链表中。 ②若在对换设备上没有被换出页的拷贝,则应将该页写到对换设备上。但为了提高对换效 率,偷页进程并不是有一个页面换出一个页面,而是先将所有要换出的页链接到一个换出页链 表上,然后再查看是否还有其他有效页要换出。当换出页面链上的页数达到某一规定值时,比 如64页,核心才真正将这些页面写入对换区 ③在对换设备上已有换出页的副本,但该页内容已被修改过。此时核心将释放该页在对换 设备上占有的空间,再重新将该页拷贝到对换设备上 (3)将换出页面写到对换设备上 当换出页面链上的页数达到规定值时,核心应将它们换出。为此,应首先为这些页面分配 连续的对换空间,以便将它们一起换出:但如果对换设备上没有足够大的连续空间,而其空 闲存储空间的总和又大于64K时,核心可采取每次换出一页的方式将它们换出。每当核心向对 换设备上写一个页面时,须首先清除该页表项的有效位,并将页面数据表项中的引用数减1。 若引用计数为0,表明已无其他进程引用该页,核心便将其页面数据表项链入空闲页链表的尾 部。若引用计数不为0,表明仍有进程共享该页,但如果该页长期未被访问,则也须将该页换 出。最后,核心将分配给该页的对换空间地址填入相应的磁盘块描述项中,并将对换使用表中 的计数加1。 请求调页 当一个进程试图存取一个其有效位为0的页面时,将产生一有效性错。此时由核心调用有 效性错处理程序加以处理。可能有下列两种情况: 种情况是如果在磁盘块描述项中找不到所缺的页,则表明此次内存访问非法,核心 将向该违例进程发出一"段违例"软中断信号;另一种情况是如果找到了所缺的页,表明此次内 存访问合法:但因该页尚未调入内存,则核心为该页分配一个页面的内存,将所缺的页调入内 存 至于如何将所缺的页调入内存,则与所缺页面从何处调入有关,可分成以下三种情况: (1)缺页在可执行文件中 如果缺页对应的磁盘块描述项中的类型是File,表示该页尚未运行过,其拷贝是在可执 文件中。因此,核心应从可执行文件中将缺页调入内存。其具体的调入过程为;根据该文件 所对应的系统区表项中的索引节点指针,找到该文件的索引节点,再把从磁盘块描述项中得到 的该页的逻辑块号作为偏移量,査找索引节点中的磁盘块号衰,便可找到该页的磁盘块号,于 是即可将该页调入内存。 (2)缺页在对换设备上
2.偷页进程 在 UNIX 系统的核心中,专门设置了一个偷页进程〈page stealer〉,其主要任务有二: 每隔一定时间增加内存中所有有效页的年龄:当有效页的年龄达到规定值后便将它换出。 (1)增加有效页年龄:一个页可计数的最大年龄取决于它的硬件设施。若只设置了两位 作为年龄域,其有效页的年龄只能取值 0、1、2 和 3。当该页的年龄为 0、1、2 时,该页处于 不可换出状态;而当其年龄达到 3 时,便可将它换出内存。每当内存中的空闲页面数低于某规 定的低限时,核心便唤醒偷页进程,由偷页进程去检查内存中的每一个活动的非上锁区,对所 有有效页的年龄字段加 1。对于那些年龄字段已增至 3 的页便不再加 1,而是将它们换出。每 当有进程访问了某个页面时,便将该页的年龄置 0。 (2)对换出页的几种处理方法:当偷页进程从内存中的有效页中找到可被换出的页后, 可采取下面三种方法对它们进行处理: ①若在对换设备上已有被换出页的拷贝,且被换出页的内容未被修改,则此时核心不必将 该页重写回对换设备上,而只需将该页的页表项的有效位清零,并将页面数据表项中的引用数 减 1,最后将该页表项放入空闲页链表中。 ②若在对换设备上没有被换出页的拷贝,则应将该页写到对换设备上。但为了提高对换效 率,偷页进程并不是有一个页面换出一个页面,而是先将所有要换出的页链接到一个换出页链 表上,然后再查看是否还有其他有效页要换出。当换出页面链上的页数达到某一规定值时,比 如 64 页,核心才真正将这些页面写入对换区. ③在对换设备上已有换出页的副本,但该页内容已被修改过。此时核心将释放该页在对换 设备上占有的空间,再重新将该页拷贝到对换设备上。 (3)将换出页面写到对换设备上 当换出页面链上的页数达到规定值时,核心应将它们换出。为此,应首先为这些页面分配 一连续的对换空间,以便将它们一起换出:但如果对换设备上没有足够大的连续空间,而其空 闲存储空间的总和又大于 64K 时,核心可采取每次换出一页的方式将它们换出。每当核心向对 换设备上写一个页面时,须首先清除该页表项的有效位,并将页面数据表项中的引用数减 1。 若引用计数为 0,表明已无其他进程引用该页,核心便将其页面数据表项链入空闲页链表的尾 部。若引用计数不为 0,表明仍有进程共享该页,但如果该页长期未被访问,则也须将该页换 出。最后,核心将分配给该页的对换空间地址填入相应的磁盘块描述项中,并将对换使用表中 的计数加 1。 3.请求调页 当一个进程试图存取一个其有效位为 0 的页面时,将产生一有效性错。此时由核心调用有 效性错处理程序加以处理。可能有下列两种情况: 一种情况是如果在磁盘块描述项中找不到所缺的页,则表明此次内存访问非法,核心 将向该违例进程发出一"段违例"软中断信号;另一种情况是如果找到了所缺的页,表明此次内 存访问合法:但因该页尚未调入内存,则核心为该页分配一个页面的内存,将所缺的页调入内 存。 至于如何将所缺的页调入内存,则与所缺页面从何处调入有关,可分成以下三种情况: (1)缺页在可执行文件中 如果缺页对应的磁盘块描述项中的类型是 File,表示该页尚未运行过,其拷贝是在可执 行文件中。因此,核心应从可执行文件中将缺页调入内存。其具体的调入过程为;根据该文件 所对应的系统区表项中的索引节点指针,找到该文件的索引节点,再把从磁盘块描述项中得到 的该页的逻辑块号作为偏移量,查找索引节点中的磁盘块号衰,便可找到该页的磁盘块号,于 是即可将该页调入内存。 (2)缺页在对换设备上
如果缺页所对应的磁盘块描述项中的类型是Disk,表示该页的拷贝是在对换设备上,则 核心将从对换设备上把该页调入内存。其调入过程为z核心先为缺页分配一内存页,修改该页 表项使之指向内存页,并将页面数据表项放入相应的散列队列中,然后把该页从对换设备上调 入内存。当I/0操作完成时,核心把请求调入该页的进程唤醒。 (3)缺页在内存页面缓冲区中 在进程运行过程中,当一页被调出后又被要求访问时,需重新将它调入。但并非每次都要 从对换设备上调入,因为被调出的页可能又被其他进程(共享时)调入到另一物理页中,这时就 可在页面缓冲池中找到该页。此时,只需适当地修改页表项等数据结构中的信息即可。 8.1.4设备管理 设备管理的主要任务是管理系统中的所有外部设备。NIX系统把设备分为两类:块设备, 用于存储信息,其对信息的存取是以信息块为单位的,如通常的磁盘、磁带等;字符设备,用于 输入/输出,其对信息的存取是以字符为单位的,如通常的终端设备、打印机等。 1.设备缓冲管理 在UNIX系统中分别为字符设备和块设备设置了缓冲池。 (1)字符设备缓冲管理 在系统中设置了一组字符缓冲区,供各种字符设备使用。其中,每个缓冲区的大小为70 个字节,包括以下四项:第一个字符的位置、最后一个字符的位置、指向下一个缓冲区的指针 和余下的用于存放64个字符的缓冲区。所有的空闲缓冲区通过链接指针c_next链接成一个 空闲缓冲队列,由队首指针 cfreelist指向其第一个缓冲区 每当设备管理程序请求一个字符缓冲区时,管理程序便从空闲缓冲区链首取得一空闲缓 冲分配给相应的设备。在设备释放缓冲区时,管理程序将它链入空闲队首。可见,空闲缓冲区 链实际上是一个栈, cfreelist指向栈顶。 在字符设备进行I/0时,核心可利用 getcf过程从空闲缓冲区链中取得一缓冲区,来收容 设备的I/0数据。当缓冲区中数据己被提取完而不再需要时,可利用 putcf过程,将缓冲区归 还到空闲链中 (2)块设备缓冲队列的结构 在系统中,为块设备配置了块设备数据缓冲区,供磁盘和磁带机使用。每个缓冲区的大小 至少应与盘块的大小相当。至于盘块的大小则随机器而异,它们一般在512~4096字节之间 由于盘块缓冲区的容量较大,使用上也较复杂,因此UNIX系统中的盘块缓冲区的组成方式不 同于字符缓冲区 在UNIX系统中,盘块缓冲区均由两部分构成:一部分是用于存放数据的缓冲区;另一部 分是缓冲控制块,也称为缓冲首都,用于存放缓冲区的管理信息,两者一一对应,但缓冲首部与 缓冲区在物理上并不相连,只是在缓冲首部中用一个指向对应缓冲区的指针将两者联系起来, 缓冲首部还包括设备号和块号,以分别指出对应的文件系统和磁盘上的数据块。注意,在 UNIX System V中,设备号并非物理设备号,而是逻辑设备号,核心把每一个文件系统看作是 个逻辑设备。缓冲首部中的状态字段指示对应缓冲区的当前状态,用于表示缓冲区是否空闲、 缓冲区是否为延迟写、是否有进程正在等待该缓冲区变为空闲、核心是否正在读或写该缓冲 区等。缓冲首部还包括两个空闲链表指针及两个散列队列指针。前者分别指向空闲链表中的 上一个和下一个缓冲区首部:后者分别指向散列队列中的上一个和下一个缓冲区首部。 为了对缓冲区进行管理,在核心中设置了一个双向链接的空闲链表。系统初启时,将所有 的缓冲首部都链入空闲链表中。当需要一个空闲缓冲区时,可利用 getblk过程从空闲链表的 首部摘下一个缓冲区:回收一个空缓冲区时,再利用 brelse过程将它挂在空闲链的末尾 为了加速对缓冲区的查找,系统把所有缓冲区按设各及块号所计算散列值的不同组织
如果缺页所对应的磁盘块描述项中的类型是 Disk,表示该页的拷贝是在对换设备上,则 核心将从对换设备上把该页调入内存。其调入过程为 z 核心先为缺页分配一内存页,修改该页 表项使之指向内存页,并将页面数据表项放入相应的散列队列中,然后把该页从对换设备上调 入内存。当 I/0 操作完成时,核心把请求调入该页的进程唤醒。 (3)缺页在内存页面缓冲区中 在进程运行过程中,当一页被调出后又被要求访问时,需重新将它调入。但并非每次都要 从对换设备上调入,因为被调出的页可能又被其他进程(共享时〉调入到另一物理页中,这时就 可在页面缓冲池中找到该页。此时,只需适当地修改页表项等数据结构中的信息即可。 8.1.4 设备管理 设备管理的主要任务是管理系统中的所有外部设备。UNIX 系统把设备分为两类:块设备, 用于存储信息,其对信息的存取是以信息块为单位的,如通常的磁盘、磁带等;字符设备,用于 输入/输出,其对信息的存取是以字符为单位的,如通常的终端设备、打印机等。 1.设备缓冲管理 在 UNIX 系统中分别为字符设备和块设备设置了缓冲池。 (1)字符设备缓冲管理 在系统中设置了一组字符缓冲区,供各种字符设备使用。其中,每个缓冲区的大小为 70 个字节,包括以下四项:第一个字符的位置、最后一个字符的位置、指向下一个缓冲区的指针 和余下的用于存放 64 个字符的缓冲区。所有的空闲缓冲区通过链接指针 c_next 链接成一个 空闲缓冲队列,由队首指针 cfreelist 指向其第一个缓冲区。 每当设备管理程序请求一个字符缓冲区时,管理程序便从空闲缓冲区链首取得一空闲缓 冲分配给相应的设备。在设备释放缓冲区时,管理程序将它链入空闲队首。可见,空闲缓冲区 链实际上是一个栈,cfreelist 指向栈顶。 在字符设备进行 I/O 时,核心可利用 getcf 过程从空闲缓冲区链中取得一缓冲区,来收容 设备的 I/O 数据。当缓冲区中数据己被提取完而不再需要时,可利用 putcf 过程,将缓冲区归 还到空闲链中。 (2)块设备缓冲队列的结构 在系统中,为块设备配置了块设备数据缓冲区,供磁盘和磁带机使用。每个缓冲区的大小 至少应与盘块的大小相当。至于盘块的大小则随机器而异,它们一般在 512~4096 字节之间。 由于盘块缓冲区的容量较大,使用上也较复杂,因此 UNIX 系统中的盘块缓冲区的组成方式不 同于字符缓冲区。 在 UNIX 系统中,盘块缓冲区均由两部分构成:一部分是用于存放数据的缓冲区;另一部 分是缓冲控制块,也称为缓冲首都,用于存放缓冲区的管理信息,两者一一对应,但缓冲首部与 缓冲区在物理上并不相连,只是在缓冲首部中用一个指向对应缓冲区的指针将两者联系起来, 缓冲首部还包括设备号和块号,以分别指出对应的文件系统和磁盘上的数据块。注意,在 UNIX System V 中,设备号并非物理设备号,而是逻辑设备号,核心把每一个文件系统看作是一 个逻辑设备。缓冲首部中的状态字段指示对应缓冲区的当前状态,用于表示缓冲区是否空闲、 缓冲区是否为延迟写、是否有进程正在等待该缓冲区变为空闲、核心是否正在读或写该缓冲 区等。缓冲首部还包括两个空闲链表指针及两个散列队列指针。前者分别指向空闲链表中的 上一个和下一个缓冲区首部:后者分别指向散列队列中的上一个和下一个缓冲区首部。 为了对缓冲区进行管理,在核心中设置了一个双向链接的空闲链表。系统初启时,将所有 的缓冲首部都链入空闲链表中。当需要一个空闲缓冲区时,可利用 getblk 过程从空闲链表的 首部摘下一个缓冲区:回收一个空缓冲区时,再利用 brelse 过程将它挂在空闲链的末尾。 为了加速对缓冲区的查找,系统把所有缓冲区按设各及块号所计算散列值的不同组织
成多个散列队列,每个散列队列仍是一个双向链表,其中的缓冲区数目不断地发生变化。各块 号的散列值用散列函数计算。一个空闲缓冲区可同时链入两个队列中,从而使对一空闲缓冲区 的查找可通过两种方式来进行:若要求获得任意一空闲缓冲区,从空闲链上摘取第一个缓冲区 即可,若要寻找一特定的空闲缓冲区,则搜索散列队列会更方便。 (3)块设备缓冲区的分配与释放 核心调用 getblk过程分配缓冲区。当要读磁盘数据时,核心首先检查要读入的盘块内容是 否已在某个缓冲区中,若发现己在某个缓冲区中,便不必再从磁盘上读入。仅当数据未在任何 缓冲区中时,核心才须从磁盘上将数据读入,这时才须为其分配一空闲缓冲区。类似地,当要把 数据写入一特定盘块时,核心应先检查该块内容是否已在某缓冲区中,仅当该块内容尚不在缓 冲区中时,才须分配一空闲缓冲区。获取空闲缓冲区时应提供的输入参数是文件系统号和磁盘 块号。 getblk过程分配缓冲区时,可分为两种情况:缓冲区在散列队列上及缓冲区不在散列队 列上 当核心用完某缓冲区时,可调用 brelse过程将它释放。 2.核心与驱动程序的接口一一设备开关表 在INIX系统中,每类设备都有一个驱动程序,用它来控制该类设备。任何一个驱动程序通 常都包含了用于执行不同操作的多个函数,如打开、关闭、启动设备、读和写等函数。为使核 心能方便地转向各函数,系统为每类设备提供了一个设备开关表,其中含有该类设备的各函数 的入口地址。 通常,字符设备和块设备的驱动程序有所不同,相应地,它们所包含的函数也不完全相同 由系统中所有字符设备的设备开关组成一张字符设备开关表,由系统中所有块设备的设备开 关组成一张块设备开关表。 3.磁盘驱动程序 磁盘驱动程序的主要功能是:把由逻辑设备号和盘块号组成的文件子系统地址转换为磁 盘上特定的扇区号:装配磁盘控制器的各个寄存器,如磁盘地址寄存器、控制状态寄存器等: 对磁盘块进行读和写。前两个功能与具体的磁盘有关,相对比较简单;而第三个功能则是驱动 程序的最主要功能 1)磁盘的读写方式 在UNIX系统中有两种读方式:一般读方式和提前读方式 在UNIX系统中有三种写方式:一般写方式、异步写方式和延迟写方式。 8.1.5文件管理 在文件系统中,为了能将文件存储到磁盘上,首先必须为之分配相应的存储空间;其次应 考虑采用何种方式将文件存储到磁盘上;第三,为简化对文件的访问和共享 1.文件存储空间的管理 (1)文件系统的组织 在UNIX系统中,文件信息存放在磁盘或磁带上,一个物理存储器中可包含一个或多个文 件卷。在UNX中,这种文件卷又称为文件系统。一个文件系统包含许多物理块 在文件系统中,0#块一般用于系统引导或空闲;1#块为超级块,用于存放文件系统的资源 管理信息,如整个文件系统的盘块数、磁盘索引节点的盘块数、空闲盘块号表及指向下一个空 闲盘块号的指针、空闲索引节点表和指向下一个空闲索引节点的指针等;从第2#块至K#块存 放磁盘索引节点:第K+1#块及其后续各块存放文件数据 (2)空闲盘块的组织 UNIX系统采用成组链接法对空闲盘块加以组织。即将若干个空闲盘块划归一个组,将每 组中的所有盘块号存放在其前一组的第一个空闲盘块号指示的盘块中,而将第一组中的所有
成多个散列队列,每个散列队列仍是一个双向链表,其中的缓冲区数目不断地发生变化。各块 号的散列值用散列函数计算。一个空闲缓冲区可同时链入两个队列中,从而使对一空闲缓冲区 的查找可通过两种方式来进行:若要求获得任意一空闲缓冲区,从空闲链上摘取第一个缓冲区 即可,若要寻找一特定的空闲缓冲区,则搜索散列队列会更方便。 (3)块设备缓冲区的分配与释放 核心调用 getblk 过程分配缓冲区。当要读磁盘数据时,核心首先检查要读入的盘块内容是 否已在某个缓冲区中,若发现己在某个缓冲区中,便不必再从磁盘上读入。仅当数据未在任何 缓冲区中时,核心才须从磁盘上将数据读入,这时才须为其分配一空闲缓冲区。类似地,当要把 数据写入一特定盘块时,核心应先检查该块内容是否已在某缓冲区中,仅当该块内容尚不在缓 冲区中时,才须分配一空闲缓冲区。获取空闲缓冲区时应提供的输入参数是文件系统号和磁盘 块号。getblk 过程分配缓冲区时,可分为两种情况:缓冲区在散列队列上及缓冲区不在散列队 列上。 当核心用完某缓冲区时,可调用 brelse 过程将它释放。 2.核心与驱动程序的接口一一设备开关表 在 UNIX 系统中,每类设备都有一个驱动程序,用它来控制该类设备。任何一个驱动程序通 常都包含了用于执行不同操作的多个函数,如打开、关闭、启动设备、读和写等函数。为使核 心能方便地转向各函数,系统为每类设备提供了一个设备开关表,其中含有该类设备的各函数 的入口地址。 通常,字符设备和块设备的驱动程序有所不同,相应地,它们所包含的函数也不完全相同。 由系统中所有字符设备的设备开关组成一张字符设备开关表,由系统中所有块设备的设备开 关组成一张块设备开关表。 3.磁盘驱动程序 磁盘驱动程序的主要功能是:把由逻辑设备号和盘块号组成的文件子系统地址转换为磁 盘上特定的扇区号:装配磁盘控制器的各个寄存器,如磁盘地址寄存器、控制状态寄存器等: 对磁盘块进行读和写。前两个功能与具体的磁盘有关,相对比较简单;而第三个功能则是驱动 程序的最主要功能。 (1)磁盘的读写方式 在 UNIX 系统中有两种读方式:一般读方式和提前读方式。 在 UNIX 系统中有三种写方式:一般写方式、异步写方式和延迟写方式。。 8.1.5 文件管理 在文件系统中,为了能将文件存储到磁盘上,首先必须为之分配相应的存储空间;其次应 考虑采用何种方式将文件存储到磁盘上;第三,为简化对文件的访问和共享。 1.文件存储空间的管理 (1)文件系统的组织 在 UNIX 系统中,文件信息存放在磁盘或磁带上,一个物理存储器中可包含一个或多个文 件卷。在 UNIX 中,这种文件卷又称为文件系统。一个文件系统包含许多物理块。 在文件系统中,0#块一般用于系统引导或空闲;1#块为超级块,用于存放文件系统的资源 管理信息,如整个文件系统的盘块数、磁盘索引节点的盘块数、空闲盘块号表及指向下一个空 闲盘块号的指针、空闲索引节点表和指向下一个空闲索引节点的指针等;从第 2#块至 K#块存 放磁盘索引节点:第 K+1#块及其后续各块存放文件数据。 (2)空闲盘块的组织 UNIX 系统采用成组链接法对空闲盘块加以组织。即将若干个空闲盘块划归一个组,将每 组中的所有盘块号存放在其前一组的第一个空闲盘块号指示的盘块中,而将第一组中的所有
空闲盘块号放入超级块的空闲盘块号表中。 (3)空闲盘块的分配与回收 ①空闲盘块的分配:当核心要从文件系统中分配一个盘块时,首先检查超级块空闲盘块表 是否已上锁,若已上锁则进程睡眠等待:否则将超级块的空闲盘块表中下一个可用盘块分配出 去。如果所分配的盘块号是超级块中的最后一个可用盘块号,由于在该盘块中存放了下一组的 所有盘块号,于是核心在给超级块中的空闲盘块号表上锁后,先将该盘块中的内容读入超级块 空闲盘块号表中;然后才将该盘块分配出去:最后将空闲盘块号表解锁,并唤醒所有等待其解 锁的进程 ②空闲盘块的回收 在回收空闲盘块时,如果超级块中的空闲盘块号表未满,可直接将回收盘块的编号放入空 闲盘块号表中。若空闲盘块号表己满,须先将空闲盘块号表中的所有盘块号复制到新回收的盘 块中,再将新回收盘块的编号放到超级块空闲盘块号表中,此块号就成了表中惟一的盘块号 2.文件的物理结构 在UNIX系统中,文件的数据存储在离散的磁盘块中,这些文件的盘块号直接或间接便可以 用直接或间接的寻址方式获得指定文件的盘块号 (1)寻址方式 ①直接寻址方式:UNIX系统中的作业以中小型为主,为了提高对文件的检索速度,宜采 用直接寻址方式。为此,在索引节点中建立了10个地址项,每个地址项中直接存放了该文件所 在的盘块号,如图8.21所示。假定一个盘块的大小为1KB,当文件长度不大于10KB时,可直接 从索引节点中得到该文件所在的全部盘块号 ②一次间接寻址方式:在UNIX系统中,可能有少数文件的长度达到了几万字节、几兆字 节、甚至更长。这时,如果采用直接寻址方式,则要在索引节点中设置几百个或更多的地址项, 这显然是不现实的。因此,UNIX系统中又提供了一次间接寻址方式。即在一次间接地址项中 存放的不再是文件的一个物理盘块号,而是先将1256个盘块号存放在一个磁盘块中,再将该 磁盘块的块号存放在这一地址项中。这里,一个盘块为1KB,一个盘块号占32位,用一次间接 地址项便可将寻址范围由10KB扩大到266KB ③多次间接寻址方式:为了进一步扩大寻址范围,又引入了二次间接和三次间接寻址方 式。二次间接寻址可将寻址范围扩大到64MB。三次间接寻址可将寻址范围扩大到16GB (2)地址转换 UNIX系统利用地址转换过程bmap将文件的字节偏移量换为文件的物理块号。这一转换 过程分两步实现∷:第一步,将字节偏移量转换为文件逻辑块号及块内偏移量;第二步,把逻辑块 号转换为文件的物理块号 3.用户文件描述符表和文件表 (1)用户文件描述符表 为了方便用户和简化系统的处理过程,在 UNIX System V中,每个进程的U区中设置了一张 用户文件描述符表。仅在用户第一次打开指定文件时,才须给出其路径名。核心先对打开请求 做仔细的检查后,便在该进程的用户文件描述符表中分配一空表工页,取该表项在用户文件描 述符表中的位移量作为文件描述符返回给用户。以后,当用户再访问该文件时,只需提供该文 件的描述符,系统根据描述符便可找到相应文件的内存索引节点。 (2)文件表 系统为了对文件进行读/写,设置了一个确定读/写位置偏移量的读/写指针。该读/写指针 应放在何处呢?是否可放在用户文件描述符表中呢?我们对此做个简单的分析。用户在读/写文 件时,可采用三种方式:多个用户读/写各自的文件:多个用户共享一个文件,但彼此独立地对 文件进行读/写:多个用户共享一个文件,且共享一个读/写指针。这样,若将读/写指针设置在
空闲盘块号放入超级块的空闲盘块号表中。 (3)空闲盘块的分配与回收 ①空闲盘块的分配:当核心要从文件系统中分配一个盘块时,首先检查超级块空闲盘块表 是否已上锁,若已上锁则进程睡眠等待:否则将超级块的空闲盘块表中下一个可用盘块分配出 去。如果所分配的盘块号是超级块中的最后一个可用盘块号,由于在该盘块中存放了下一组的 所有盘块号,于是核心在给超级块中的空闲盘块号表上锁后,先将该盘块中的内容读入超级块 空闲盘块号表中;然后才将该盘块分配出去:最后将空闲盘块号表解锁,并唤醒所有等待其解 锁的进程。 ②空闲盘块的回收 在回收空闲盘块时,如果超级块中的空闲盘块号表未满,可直接将回收盘块的编号放入空 闲盘块号表中。若空闲盘块号表己满,须先将空闲盘块号表中的所有盘块号复制到新回收的盘 块中,再将新回收盘块的编号放到超级块空闲盘块号表中,此块号就成了表中惟一的盘块号。 2.文件的物理结构 在 UNIX 系统中,文件的数据存储在离散的磁盘块中,这些文件的盘块号直接或间接便可以 用直接或间接的寻址方式获得指定文件的盘块号。 (1)寻址方式 ①直接寻址方式:UNIX 系统中的作业以中小型为主,为了提高对文件的检索速度,宜采 用直接寻址方式。为此,在索引节点中建立了 10 个地址项,每个地址项中直接存放了该文件所 在的盘块号,如图 8.21 所示。假定一个盘块的大小为 1KB,当文件长度不大于 10KB 时,可直接 从索引节点中得到该文件所在的全部盘块号。 ②一次间接寻址方式:在 UNIX 系统中,可能有少数文件的长度达到了几万字节、几兆字 节、甚至更长。这时,如果采用直接寻址方式,则要在索引节点中设置几百个或更多的地址项, 这显然是不现实的。因此,UNIX 系统中又提供了一次间接寻址方式。即在一次间接地址项中 存放的不再是文件的一个物理盘块号,而是先将 1~256 个盘块号存放在一个磁盘块中,再将该 磁盘块的块号存放在这一地址项中。这里,一个盘块为 1KB,一个盘块号占 32 位,用一次间接 地址项便可将寻址范围由 lOKB 扩大到 266KB。 ③多次间接寻址方式:为了进一步扩大寻址范围,又引入了二次间接和三次间接寻址方 式。二次间接寻址可将寻址范围扩大到 64MB。三次间接寻址可将寻址范围扩大到 16GB。 (2)地址转换 UNIX 系统利用地址转换过程 bmap 将文件的字节偏移量换为文件的物理块号。这一转换 过程分两步实现:第一步,将字节偏移量转换为文件逻辑块号及块内偏移量;第二步,把逻辑块 号转换为文件的物理块号。 3.用户文件描述符表和文件表 (1)用户文件描述符表 为了方便用户和简化系统的处理过程,在 UNIX System V 中,每个进程的 U 区中设置了一张 用户文件描述符表。仅在用户第一次打开指定文件时,才须给出其路径名。核心先对打开请求 做仔细的检查后,便在该进程的用户文件描述符表中分配一空表工页,取该表项在用户文件描 述符表中的位移量作为文件描述符返回给用户。以后,当用户再访问该文件时,只需提供该文 件的描述符,系统根据描述符便可找到相应文件的内存索引节点。 (2)文件表 系统为了对文件进行读/写,设置了一个确定读/写位置偏移量的读/写指针。该读/写指针 应放在何处呢?是否可放在用户文件描述符表中呢?我们对此做个简单的分析。用户在读/写文 件时,可采用三种方式:多个用户读/写各自的文件;多个用户共享一个文件,但彼此独立地对 文件进行读/写:多个用户共享一个文件,且共享一个读/写指针。这样,若将读/写指针设置在
文件描述符表项中,对前两种情况固然可行,但要实现对读/写指针的共享就很困难。为解决此 问题,在UNIX系统中引入了文件表,文件表项中存放文件的读/写指针,这样对上述三种读/写 要求都能很好地满足。 4.目录管理 为了加速对文件目录的查找,在UNIX系统中,将文件名和文件说明分开,由文件说明形成 个称为索引节点的数据结构,而相应的文件目录项则只由文件名和对应的索引节点号构成 (1)索引节点 磁盘索引节点:索引节点是一个数据结构,其中存放文件的说明信息。索引节点以静态形 式存放在磁盘上,故又称为磁盘索引节点。每个文件都有惟一的一个磁盘索引节点,它由下述 各字段构成:文件所有者标识符、文件类型、文件存取权限、存放文件的物理地址、文件长度、 文件联结计数、文件存取时间 内存索引节点:为了加快文件的存取速度和减轻磁盘I/0的压力,专门在内存中建立了 个内存索引节点表,将那些要被引用的磁盘索引节点复制到内存索引节点表中,并增加了如下 字段:索引节点号、内存索引节点状态、内存索引节点引用计数、设备号和内存索引节点指 针。 (2)磁盘索引节点的分配与回收 分配过程 ialloc:每当核心创建一新文件时,都要为之分配一空闲磁盘索引节点。如果 分配成功,便再分配一内存索引节点 回收过程 ifree:当要删除某文件时,应回收其所占用的盘块及相应的磁盘索引节点。过程 ifree便是用于回收磁盘索引节点的。 (3)内存索引节点的分配与回收 分配过程iget:主要功能是分配内存索引节点,其输入参数是文件系统号和索引节点。 回收过程iput:输入参数是指向内存i节点的指针。其主要功能是对指定的内存索引节 点进行减1操作。若结果为0,则回收该内存i节点。若它已做过修改,还须将它写回磁 盘后再回收,然后将它链入内存空闲i节点表中。若其磁盘i节点的联结计数也为0,便 删除该文件,并回收分配给该文件的磁盘i节点和磁盘数据块。 (4)构造目录和删除目录 文件系统的基本功能是实现按名存取,这是通过文件目录来实现的。UNIX系统中的每个 目录项由文件名及其相应的索引节点号组成,其中文件名占14个字节,索引节点号占2个字 节。通常,每个文件都在文件目录中有一个目录项,通过查找文件目录可找到该文件的目录项 和对应的索引节点,进而找到文件存放的物理位置。对于可供多个用户共享的文件,则它往往 会有多个目录工页。如果要将文件删除掉,其目录便也无存在的必要,因此也应将其目录项删 除掉 构造目录:每当创建一个新文件时,系统都要在其父目录文件中为之构造一个目录项。在 UNIX系统中,构造目录的任务由 makenode过程完成。在创建一个新文件时,由系统调用 creat 调用该过程来为新文件构造一个目录项。 makenode过程首先调用 ialloc过程来为新建的文 件分配一磁盘索引节点和内存索引节点,若分配失败便返回:当分配成功时,须先设置内存索 引节点的初值,然后调用写目录过程,将用户提供的文件名与分配给文件的磁盘索引节点号 起构成一新目录项,再将它记入其父目录文件中。 删除目录:当用户已不再需要某个文件时,应将它从文件系统中删除,以便及时腾出存储 空间。由于UNIX系统支持文件的共享,而当文件正被多个进程共享时,不允许任何一个用户将 该文件删除。这也是UNIX系统中不存在一条用于删除文件的系统调用的真正原因。当一个用 户(进程〉己不再需要某文件时,只能利用系统调用 unlink请求清除进程与该文件的联结。此 时,系统须对该文件的联结计数执行减1操作,并相应地删除该用户(进程)的一个指定文件目
文件描述符表项中,对前两种情况固然可行,但要实现对读/写指针的共享就很困难。为解决此 问题,在 UNIX 系统中引入了文件表,文件表项中存放文件的读/写指针,这样对上述三种读/写 要求都能很好地满足。 4.目录管理 为了加速对文件目录的查找,在 UNIX 系统中,将文件名和文件说明分开,由文件说明形成 一个称为索引节点的数据结构,而相应的文件目录项则只由文件名和对应的索引节点号构成。 (1)索引节点 磁盘索引节点:索引节点是一个数据结构,其中存放文件的说明信息。索引节点以静态形 式存放在磁盘上,故又称为磁盘索引节点。每个文件都有惟一的一个磁盘索引节点,它由下述 各字段构成:文件所有者标识符、文件类型、文件存取权限、存放文件的物理地址、文件长度、 文件联结计数、文件存取时间。 内存索引节点:为了加快文件的存取速度和减轻磁盘 I/0 的压力,专门在内存中建立了一 个内存索引节点表,将那些要被引用的磁盘索引节点复制到内存索引节点表中,并增加了如下 字段:索引节点号、 内存索引节点状态、内存索引节点引用计数、设备号和内存索引节点指 针。 (2)磁盘索引节点的分配与回收 分配过程 ialloc:每当核心创建一新文件时,都要为之分配一空闲磁盘索引节点。如果 分配成功,便再分配一内存索引节点。 回收过程 ifree:当要删除某文件时,应回收其所占用的盘块及相应的磁盘索引节点。过程 ifree 便是用于回收磁盘索引节点的。 (3)内存索引节点的分配与回收 分配过程 iget:主要功能是分配内存索引节点,其输入参数是文件系统号和索引节点。 回收过程 iput:输入参数是指向内存 i 节点的指针。其主要功能是对指定的内存索引节 点进行减 1 操作。若结果为 0,则回收该内存 i 节点。若它已做过修改,还须将它写回磁 盘后再回收,然后将它链入内存空闲 i 节点表中。若其磁盘 i 节点的联结计数也为 0,便 删除该文件,并回收分配给该文件的磁盘 i 节点和磁盘数据块。 (4)构造目录和删除目录 文件系统的基本功能是实现按名存取,这是通过文件目录来实现的。UNIX 系统中的每个 目录项由文件名及其相应的索引节点号组成,其中文件名占 14 个字节,索引节点号占 2 个字 节。通常,每个文件都在文件目录中有一个目录项,通过查找文件目录可找到该文件的目录项 和对应的索引节点,进而找到文件存放的物理位置。对于可供多个用户共享的文件,则它往往 会有多个目录工页。如果要将文件删除掉,其目录便也无存在的必要,因此也应将其目录项删 除掉。 构造目录:每当创建一个新文件时,系统都要在其父目录文件中为之构造一个目录项。在 UNIX 系统中,构造目录的任务由 makenode 过程完成。在创建一个新文件时,由系统调用 creat 调用该过程来为新文件构造一个目录项。makenode 过程首先调用 ialloc 过程来为新建的文 件分配一磁盘索引节点和内存索引节点,若分配失败便返回:当分配成功时,须先设置内存索 引节点的初值,然后调用写目录过程,将用户提供的文件名与分配给文件的磁盘索引节点号一 起构成一新目录项,再将它记入其父目录文件中。 删除目录:当用户已不再需要某个文件时,应将它从文件系统中删除,以便及时腾出存储 空间。由于 UNIX 系统支持文件的共享,而当文件正被多个进程共享时,不允许任何一个用户将 该文件删除。这也是 UNIX 系统中不存在一条用于删除文件的系统调用的真正原因。当一个用 户(进程〉己不再需要某文件时,只能利用系统调用 unlink 请求清除进程与该文件的联结。此 时,系统须对该文件的联结计数执行减 1 操作,并相应地删除该用户(进程)的一个指定文件目