diff --git a/Operate-System/0-summary-ex.md b/Operate-System/0-summary-ex.md index 18eac54..e2a506e 100644 --- a/Operate-System/0-summary-ex.md +++ b/Operate-System/0-summary-ex.md @@ -126,26 +126,6 @@ $D.$快速处理 ## 操作系统的运行环境 -**例题** 下列关于系统调用的说法中,正确的是()。 - -Ⅰ.用户程序设计时,使用系统调用命令,该命令经过编译后,形成若干参数和陷入($trap$)指令 - -Ⅱ.用户程序设计时,使用系统调用命令,该命令经过编译后,形成若干参数和屏蔽中断指令 - -Ⅲ.系统调用功能是操作系统向用户程序提供的接口 - -Ⅳ.用户及其应用程序和应用系统是通过系统调用提供的支持和服务来使用系统资源完成其操作的 - -$A.$Ⅰ、Ⅲ - -$B.$Ⅱ、Ⅳ - -$C.$Ⅰ、Ⅲ、Ⅳ - -$D.$Ⅱ、Ⅲ、Ⅳ - -解:$C$。Ⅰ正确:系统调用需要从用户应用程序调用系统的接口,用户态进入核心态,触发$trap$指令。(如基于$x86$的$Linux$系统,该指令为$int\,Ox80$或$sysenter$。Ⅱ是干扰项,屏蔽中断指令由外部的异步操作造成,由操作系统接收到外部操作而产生对现场进行保护,程序设计无法形成屏蔽中断指令。Ⅲ正确:系统调用的概念。Ⅳ正确:操作系统是一层接口,对上层提供服务,对下层进行抽象。它通过系统调用向其上层的用户、应用程序和应用系统提供对系统资源的使用。 - **例题** 下列操作系统的各个功能组成部分中,()可不需要硬件的支持。 $A.$进程调度 @@ -156,7 +136,9 @@ $C.$地址映射 $D.$中断系统 -解:$A$。中断系统和地址映射显然都需要硬件支持,因为中断指令和地址映射中的重定位都是离不开硬件支持的。而时钟管理中,重置时钟等是由硬件直接完成的。进程调度由调度算法决定$CPU$使用权,由操作系统实现,无须硬件的支持。 +解:$A$。中断系统和地址映射显然都需要硬件支持,因为中断指令和地址映射中的重定位都是离不开硬件支持的。而时钟管理中,重置时钟等是由硬件直接完成的。进程调度由调度算法决定$CPU$使用权,由操作系统实现,无须硬件的支持。 + +### 处理机状态 **例题** 计算机区分核心态和用户态指令后,从核心态到用户态的转换是由操作系统程序执行后完成的,而用户态到核心态的转换则是由()完成的。 @@ -196,6 +178,20 @@ $D.$关中断指令 解:$D$。$trap$指令、跳转指令和压栈指令均可以在用户态执行,其中$trap$指令负责由用户态转换为内核态,跳转指令是指改变程序执行顺序的指令,压栈指令即进栈指令,与出栈(弹栈)指令相对,用于将数据压入数据栈。关中断指令为特权指令,指关闭中断机制的指令,必须在核心态才能执行,选$D$。关中断在中断机制中在第一步,用于完整保护现场避免指令打扰,也用于原语执行保持完整,关中断后要执行开中断指令。 +**例题** 假定下列指令已装入指令寄存器,则执行时不可能导致$CPU$从用户态变为内核态(系统态)的是()。 + +$A.DIV\,R0,R1;(R0)/(R1)\rightarrow R0$ + +$B.INT\,n;$产生软中断 + +$C.NOT\,R0;$寄存器$R0$的内容取非 + +$D.MOV\,R0,addr;$把地址$addr$处的内存数据放入寄存器$R0$ + +解:$C$。为什么会产生由用户态转换核心态?因为可能出现异常导致中断。$A$可能除数$R0$为$0$导致异常;$B$由于软中断,所以是一个中断指令,所以会转为核心态;$D$是将内存放入寄存器中,可能产生缺页异常(即放不进去);$C$是取反,只变一位数字,不会产生异常。 + +### 中断 + **例题** 内部异常(内中断)可分为故障($fault$)、陷阱($trap$)和终止($abort$)三类。下列有关内部异常的叙述中,错误的是()。 $A.$内部异常的产生与当前执行指令相关 @@ -220,23 +216,11 @@ $D.Cache$中的内容 解:$B$。$PC$值由中断隐指令自动保存。通用寄存器内容由操作系统保存。$TLB$称为转译后备缓冲器,与$Cache$一样是$CPU$缓存的一种,都是由各自的缓存器保存。 -**例题** 假定下列指令已装入指令寄存器,则执行时不可能导致$CPU$从用户态变为内核态(系统态)的是()。 - -$A.DIV\,R0,R1;(R0)/(R1)\rightarrow R0$ - -$B.INT\,n;$产生软中断 - -$C.NOT\,R0;$寄存器$R0$的内容取非 - -$D.MOV\,R0,addr;$把地址$addr$处的内存数据放入寄存器$R0$ - -解:$C$。为什么会产生由用户态转换核心态?因为可能出现异常导致中断。$A$可能除数$R0$为$0$导致异常;$B$由于软中断,所以是一个中断指令,所以会转为核心态;$D$是将内存放入寄存器中,可能产生缺页异常(即放不进去);$C$是取反,只变一位数字,不会产生异常。 - **例题** 定时器产生时钟中断后,由时钟中断服务程序更新的部分内容是()。 I.内核中时钟变量的值 -Ⅱ.当前进程占用CPU的时间 +Ⅱ.当前进程占用$CPU$的时间 Ⅲ.当前进程在时间片内的剩余执行时间 @@ -250,6 +234,28 @@ $D.$Ⅰ、Ⅱ、Ⅱ 解:$D$。时钟中断的主要工作是处理和时间有关的信息及决定是否执行调度程序。和时间有关的所有信息包括系统时间、进程的时间片、延时、使用$CPU$的时间、各种定时器,因此Ⅰ、Ⅱ、Ⅲ均正确。 +### 系统调用 + +**例题** 下列关于系统调用的说法中,正确的是()。 + +Ⅰ.用户程序设计时,使用系统调用命令,该命令经过编译后,形成若干参数和陷入($trap$)指令 + +Ⅱ.用户程序设计时,使用系统调用命令,该命令经过编译后,形成若干参数和屏蔽中断指令 + +Ⅲ.系统调用功能是操作系统向用户程序提供的接口 + +Ⅳ.用户及其应用程序和应用系统是通过系统调用提供的支持和服务来使用系统资源完成其操作的 + +$A.$Ⅰ、Ⅲ + +$B.$Ⅱ、Ⅳ + +$C.$Ⅰ、Ⅲ、Ⅳ + +$D.$Ⅱ、Ⅲ、Ⅳ + +解:$C$。Ⅰ正确:系统调用需要从用户应用程序调用系统的接口,用户态进入核心态,触发$trap$指令。(如基于$x86$的$Linux$系统,该指令为$int\,Ox80$或$sysenter$。Ⅱ是干扰项,屏蔽中断指令由外部的异步操作造成,由操作系统接收到外部操作而产生对现场进行保护,程序设计无法形成屏蔽中断指令。Ⅲ正确:系统调用的概念。Ⅳ正确:操作系统是一层接口,对上层提供服务,对下层进行抽象。它通过系统调用向其上层的用户、应用程序和应用系统提供对系统资源的使用。 + **例题** 下列关于系统调用的叙述中,正确的是()。 Ⅰ.在执行系统调用服务程序的过程中,$CPU$处于内核态 @@ -270,6 +276,8 @@ $D.$仅Ⅱ、Ⅲ、Ⅳ 解:$C$。用户可以在用户态调用操作系统的服务,但执行具体的系统调用服务程序是处于内核态的,Ⅰ正确;设备管理属于操作系统的职能之一,包括对输入/输出设备的分配、初始化、维护等,用户程序需要通过系统调用使用操作系统的设备管理服务,Ⅱ正确;操作系统不同,底层逻辑、实现方式均不相同,为应用程序提供的系统调用接口也不同,Ⅲ错误;系统调用是用户在程序中调用操作系统提供的子功能,Ⅳ正确。 +## 操作系统的体系结构 + **例题** 相对于传统操作系统结构,采用微内核结构设计和实现操作系统具有诸多好处,下列()是微内核结构的特点。 Ⅰ.使系统更高效 diff --git a/Operate-System/0-summary.md b/Operate-System/0-summary.md index c1c0758..9ccc91d 100644 --- a/Operate-System/0-summary.md +++ b/Operate-System/0-summary.md @@ -190,9 +190,9 @@ + 分布式操作系统:具有分布性和并行性,系统中各个计算机地位相同,任何工作可以分布在这些计算机上,并行写协同完成任务。 + 个人计算机操作系统:方便个人使用的操作系统,如$Windows\,10$、$MacOS$。 -## 操作系统的运行环境 +## 操作系统运行环境 -### 操作系统的运行机制 +### 操作系统运行机制 #### 两种指令 @@ -208,7 +208,7 @@ + 置时钟:若在用户态下执行“置时钟指令”,则一个用户进程可在时间片还未到之前把时钟改回去,从而导致时间片永远不会用完,进而导致该用户进程一直占用$CPU$,这显然不合理。 + 输入输出:涉及中断指令,而中断处理由系统内核负责,工作在核心态。 -#### 两种处理器状态 +#### 处理机状态 操作系统根据处理器状态来判断是否可以使用特权指令。 @@ -217,7 +217,7 @@ + 用户态(目态):只能执行非特权指令。 + 核心态(管态):可以执行特权指令。 -#### 两种程序 +#### 程序类别 根据程序所可以使用指令的权限,程序分为两种: diff --git a/Operate-System/1-process-management-ex.md b/Operate-System/1-process-management-ex.md new file mode 100644 index 0000000..940fef3 --- /dev/null +++ b/Operate-System/1-process-management-ex.md @@ -0,0 +1,143 @@ +# 进程管理习题 + +## 进程与线程 + +### 进程 + +#### 进程概念 + +**例题** 进程与程序的根本区别是()。 + +$A.$静态和动态特点 + +$B.$是不是被调入内存 + +$C.$是不是具有就绪、运行和等待三种状态 + +$D.$是不是占有处理器 + +解:$A$。动态性是进程最重要的特性,以此来区分文件形式的静态程序。操作系统引入进程的概念,是为了从变化的角度动态地分析和研究程序的执行。 + +**例题** 同一程序经过多次创建,运行在不同的数据集上,形成了()的进程。 + +$A.$不同 + +$B.$相同 + +$C.$同步 + +$D.$互斥 + +解:$A$。一个进程是程序在一个数据集上的一次运行过程。运行于不同的数据集,将会形成不同的进程。 + +#### 进程结构 + +**例题** 若一个进程实体由$PCB$、共享正文段、数据堆段和数据栈段组成,请指出下列$C$语言程序中的内容及相关数据结构各位于哪一段中。 + +Ⅰ.全局赋值变量 + +Ⅱ.未赋值的局部变量 + +Ⅲ.函数调用实参传递值 + +Ⅳ.用`malloc()`要求动态分配的存储区 + +Ⅴ.常量值(如`1995`、`"string"`) + +Ⅵ.进程的优先级 + +$A.PCB$ + +$B.$正文段 + +$C.$堆段 + +$D.$栈段 + +解:$B$、$D$、$D$、$C$、$B$、$A$。$C$语言编写的程序在使用内存时一般分为三个段,它们一般是正文段(即代码和赋值数据段)、数据堆段和数据栈段。二进制代码和常量存放在正文段,动态分配的存储区在数据堆段,临时使用的变量在数据栈段。由此,我们可以确定全局赋值变量在正文段赋值数据段,未赋值的局部变量和实参传递在栈段,动态内存分配在堆段,常量在正文段,进程的优先级与进程直接相关,放在$PCB$内。 + +#### 进程状态 + +**例题** 下面的叙述中,正确的是()。 + +$A.$进程获得处理器运行是通过调度得到的 + +$B.$优先级是进程调度的重要依据,一旦确定不能改动 + +$C.$在单处理器系统中,任何时刻都只有一个进程处于运行态 + +$D.$进程申请处理器而得不到满足时,其状态变为阻塞态 + +解:$A$。选项$B$错在优先级分静态和动态两种,动态优先级是根据运行情况而随时调整的。选项$C$错在至多只存在一个运行态,系统发生死锁时有可能进程全部都处于阻塞态,或无进程任务,$CPU$空闲。选项$D$错在进程申请处理器得不到满足时就处于就绪态,等待处理器的调度。 + +#### 进程优先级 + +**例题** 下列选项中,降低进程优先级的合理时机是()。 + +$A.$进程时间片用完 + +$B.$进程刚完成$I/O$操作,进入就绪队列 + +$C.$进程长期处于就绪队列 + +$D.$进程从就绪态转为运行态 + +解:$A$。$A$中进程时间片用完,可降低其优先级以让其他进程被调度进入执行状态避免不断占用处理机,使得其他进程产生饥饿。$B$中进程刚完成$I/O$,进入就绪队列等待被处理机调度,为了让其尽快处理$I/O$结果,因此应提高优先级。$C$中进程长期处于就绪队列,为不至于产生饥饿现象,也应适当提高优先级。$D$中进程的优先级不应该在此时降低,如果此时降低了可能会被抢占,导致进程反复切换,降低处理效率,而应在时间片用完后再降低。 + +#### 父子进程 + +**例题** 下列关于父进程与子进程的叙述中,错误的是()。 + +$A.$父进程与子进程可以并发执行 + +$B.$父进程与子进程共享虚拟地址空间 + +$C.$父进程与子进程有不同的进程控制块 + +$D.$父进程与子进程不能同时使用同一临界资源 + +解:$B$。父进程与子进程当然可以并发执行,$A$正确。父进程可与子进程共享一部分资源,但不能共享虚拟地址空间,在创建子进程时,会为子进程分配资源,如虚拟地址空间等,$B$错误。临界资源一次只能为一个进程所用,$D$正确。进程控制块$PCB$是进程存在的唯一标志,每个进程都有自己的$PCB$,$C$正确。 + +#### 进程通信 + +**例题** 下列关于管道($Pipe$)通信的叙述中,正确的是()。 + +$A.$一个管道可实现双向数据传输 + +$B.$管道的容量仅受磁盘容量大小限制 + +$C.$进程对管道进行读操作和写操作都可能被阻塞 + +$D.$一个管道只能有一个读进程或一个写进程对其操作 + +解:$C$。管道类似于通信中半双工信道的进程通信机制,一个管道可以实现双向的数据传输,但是同一时刻只能最多有一个方向的传输,不能两个方向同时进行,所以必须使用两个管道才能实现双向数据传输(特指同时),$A$错误。管道的容量大小通常为内存上的一页,它的大小并不受磁盘容量大小的限制,$B$错误。当管道满时,进程在写管道会被阻塞,而当管道空时,进程在读管道会被阻塞,因此选$C$。一个管道可以被多个读进程或写进程操作,但是同一时间只能有一个读进程或一个写进程对其操作,$D$没有限制是同时所以错误。 + +### 线程 + +#### 线程概念 + +**例题** 系统动态$DLL$库中的系统线程,被不同的进程所调用,它们是()的线程。 + +$A.$不同 + +$B.$相同 + +$C.$可能不同,也可能相同 + +$D.$不能被调用 + +解:$B$。进程是暂时的,程序是永久的;进程是动态的,程序是静态的;进程至少由代码、数据和$PCB$组成,程序仅需代码和数据即可;程序代码经过多次创建可对应不同的进程,而同一个系统的进程(或线程)可以由系统调用的方法被不同的进程(或线程)多次使用。 + +#### 多线程系统 + +**例题** 在以下描述中,()并不是多线程系统的特长。 + +$A.$利用线程并行地执行矩阵乘法运算 + +$B.Web$服务器利用线程响应$HTTP$请求 + +$C.$键盘驱动程序为每个正在运行的应用配备一个线程,用以响应该应用的键盘输入 + +$D.$基于$GUI$的调试程序用不同的线程分别处理用户输入、计算和跟踪等操作 + +解:$C$。对于题目所提的不算多线程系统的特长,即找出下面情形可以用一个线程就可以完成的情况。整个系统只有一个键盘,而且键盘输入是人的操作,速度比较慢,完全可以使用一个线程来处理整个系统的键盘输入。 \ No newline at end of file diff --git a/Operate-System/1-process-management.md b/Operate-System/1-process-management.md index 6ace5c4..ae2b040 100644 --- a/Operate-System/1-process-management.md +++ b/Operate-System/1-process-management.md @@ -2,74 +2,92 @@ ## 进程与线程 -### 进程的概念 +### 进程概念 + 程序指一个指令序列。 ++ 进程为了满足操作系统的并发性和共享性。 + 系统为每个运行的程序配置一个数据结构,称为**进程控制块PCB**,用来描述进程的各种信息,如程序代码存放位置。 -+ PCB、程序段、数据段三个部分构成了进程实体(进程映像),简称为进程。 -+ 创建进程就是创建PCB,销毁进程就是销毁PCB,PCB是进程存在的唯一标志。 ++ $PCB$、程序段、数据段三个部分构成了进程实体(进程映像),简称为进程。 ++ 创建进程就是创建$PCB$,销毁进程就是销毁$PCB$,$PCB$是进程存在的唯一标志。 ++ 进程映像是静态的,而进程是动态的。 + 进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。 ++ 系统资源这里指处理机、存储器和其他设备服务于某个进程的时间单位。 -#### 进程的结构 +#### 进程结构 + 程序段:包括程序代码,程序运行时使用、产生的运算数据。如全局变量、局部变量、宏定义的常量。 + 数据段:存放程序运行过程中处理的各种数据。 -+ PCB:操作系统用PCB来管理进程,所以PCB包含所有管理进程所需的信息。 ++ $PCB$:操作系统用$PCB$来管理进程,所以$PCB$包含所有管理进程所需的信息。 + 进程描述信息: - + 进程标识符PID。 - + 用户标识符UID。 + + 进程标识符$PID$:标识进程。 + + 用户标识符$UID$:标识进程归属的用户1,用于共享和保护服务。 + 进程控制和管理信息: - + 进程当前状态。 - + 进程优先级。 - + 资源分配清单: - + 程序段指针。 + + 进程当前状态:进程状态信息,作为处理机发分配调度的依据。 + + 进程优先级:进程抢占处理机的优先级。 + + 代码运行入口地址。 + + 程序外村地址。 + + 进入内存时间。 + + 处理机占用时间。 + + 信号量使用。 + + 资源分配清单:说明有关内存地址空间或虚拟地址空间的状况,打开文件的列标与使用的输入输出设备信息。 + + 代码段指针。 + 数据段指针。 + + 堆栈段指针。 + + 文件描述符。 + 键盘。 + 鼠标。 - + 处理机相关信息: - + 各种寄存器值。 + + 处理机相关信息:主要处理机中各种寄存器值。 + + 通用寄存器值。 + + 地址寄存器值。 + + 控制寄存器值。 + + 标志寄存器值。 + + 状态字。 -#### 进程的特征 +#### 进程特征 + 动态性:是进程最基本的特征,进程是程序的一次执行过程,是动态地产生、变化和消亡的。 + 并发性:内存中有多个进程实体,各进程可并发执行。 + 独立性:进程是资源分配、接受调度、能独立运行、独立获得资源、独立接受调度的基本单位。 + 异步性:各进程按各自独立的、不可预知的速度向前推进,操作系统要提供“进程同步机制”来解决异步问题。 -+ 结构性:每个进程都会配置一个PCB。结构上看,进程由程序段、数据段、PCB组成。 ++ 结构性:每个进程都会配置一个$PCB$。结构上看,进程由程序段、数据段、$PCB$组成。 -#### 进程的组织 +#### 进程组织 -当一个系统中存在多格PCB时,需要以适当的方式组织PCB。 +当一个系统中存在多格$PCB$时,需要以适当的方式组织$PCB$。 + 链接方式: - + 按照进程状态将PCB分为多个队列。如执行指针(指针数为最大执行并行数)、就绪队列指针(一般会把优先级高的进程放在队头)、阻塞队列指针(许多操作系统会根据阻塞原因的不同将其分为多个阻塞队列)。 + + 按照进程状态将$PCB$分为多个队列。如执行指针(指针数为最大执行并行数)、就绪队列指针(一般会把优先级高的进程放在队头)、阻塞队列指针(许多操作系统会根据阻塞原因的不同将其分为多个阻塞队列)。 + 操作系统持有指向各个队列的指针。 + 索引方式: + 根据进程状态的不同建立索引表。如执行指针、就绪表指针、阻塞表指针。 + 操作系统持有指向各个索引表的指针。 -### 进程的状态 +### 进程状态 #### 基本进程状态 具有三种基本状态和其他两种状态: -+ 运行态:占有CPU并已经在CPU上运行。 -+ 就绪态:已经具备运行条件,但是由于没有空闲CPU,导致暂时不能运行。 -+ 阻塞态(等待态):因等待某一事件而暂时不能运行,只有分配到位才能考虑分配CPU。 -+ 创建态(新建态):为进程分配所需的内存空间等系统资源,为其创建、初始化PCB。 -+ 终止态(结束态):进程运行结束或出现错误导致进程被撤销,操作系统需要回收进程资源,撤销PCB等工作,以防止内存泄漏。 ++ 运行态:占有$CPU$并已经在$CPU$上运行。 ++ 就绪态:已经具备运行条件(除处理机外的一切所需资源),但是由于没有空闲$CPU$,导致暂时不能运行。 ++ 阻塞态(等待态):因等待某一事件而暂时不能运行,只有分配其他资源到位才能考虑分配$CPU$。 ++ 创建态(新建态):为进程分配所需的内存空间等系统资源,将转为就绪态。 + + 申请一个空白$PCB$。 + + 向$PCB$填写一些控制和管理进程的信息。 + + 系统为进程分配运行所需资源。 + + 进程转为就绪态。 ++ 终止态(结束态):进程运行结束或出现错误导致进程被撤销,操作系统需要回收进程资源,撤销$PCB$等工作,以防止内存泄漏。 + 挂起态:暂时不能获得服务,进程映像调到外存等待(阻塞态的进程映像还在内存中等待)。分为: - + 就绪挂起态。 - + 阻塞挂起态。 + + 就绪挂起态:准备好后在外存中。 + + 阻塞挂起态:等待事件在外存中。 -#### 进程状态的转换 +#### 进程状态转换 + 创建态到就绪态:系统完成创建进程等工作并准备好处理机等资源。 -+ 就绪态到运行态:占有CPU资源,进程被调用。 -+ 运行态到就绪态:时间片到或处理机(包含CPU和内存的一系列硬件)被抢占。 -+ 运行态到阻塞态:进程主动用系统调用的方式申请某种系统资源,或请求等待某个事件发生。 -+ 阻塞态到就绪态:申请的资源被分配或等待的事件发生。 ++ 就绪态到运行态:占有$CPU$资源,进程被调用。 ++ 运行态到就绪态:时间片到或处理机(包含$CPU$和内存的一系列硬件)被抢占。 ++ 运行态到阻塞态:进程主动用系统调用的方式申请某种系统资源(由用户态程序调用操作系统内核),或请求等待某个事件发生。 ++ 阻塞态到就绪态:申请的资源被分配或等待的事件发生,是被动发生。 + 运行态到终止态:进程运行结束或运行过程中遇到不可修复的错误。 + 就绪挂起态到就绪态:激活。 + 就绪态到就绪挂起态:挂起。 @@ -79,26 +97,28 @@ + 运行态到就绪挂起态:运行中内存空间不足,或优先级更高的进程进入队列。 + 创建态到就绪挂起态:创建后发现内存空间不足。 -### 进程的控制 +### 进程控制 -#### 进程控制的概念 +#### 进程控制概念 + 进程控制指对系统中的所有进程实施有效的管理,具有创建新进程、撤销已有进程、实现进程状态转换功能。 -+ 如进程组织所说,通过将PCB指针放入各种状态的进程队列中转换进程状态来实现控制。 -+ 进程控制由原语实现。 ++ 如进程组织所说,通过将$PCB$指针放入各种状态的进程队列中转换进程状态来实现控制。 ++ 进程控制由**原语**实现。 + 特点是执行期间不能中断。 + 这种不能中断的操作就是原子操作。 + 原语采取“关中断指令”(不监听外部中断信息)和“开中断指令”(开始监听外部中断信息)实现。 + 关/开中断指令的权限很大,所以必然是核心态下执行的特权指令。从而原语必然运行在核心态。 -#### 进程控制的原语 +#### 进程控制原语 + +允许一个进程创建另一个进程。此时创建者称为父进程,被创建的进程称为子进程。子进程可以继承父进程所拥有的资源。当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。此外,在撤销父进程时,必须同时撤销其所有的子进程。 + 过程的创建: + 创建原语: - + 申请空白PCB。 - + 为新进程分配所需资源。 - + 初始化PCB。 - + 将PCB插入就绪队列。 + + 分配一个唯一的进程标识号$PID$,申请空白$PCB$,若申请失败,则创建失败。 + + 为新进程分配所需资源,若资源不足,则进入阻塞态。 + + 初始化$PCB$,主要包括标志信息、处理机状态信息、处理机控制信息、进程优先级。 + + 将$PCB$插入就绪队列。 + 引起进程创建的事件: + 用户登录:分时系统中,用户登录成功,系统会为其建立一个新进程。 + 作业调度:多道批处理系统中,有新的作业进入内存时,会为其创建一个新进程。 @@ -106,77 +126,84 @@ + 应用请求:由用户进程主动请求创建一个子进程。 + 进程终止: + 撤销原语: - + 从PCB集合中找到终止进程的PCB。 - + 若进程正在运行,则立刻剥夺其CPU交给其他进程。 - + 若是普通的终止,父进程终止时会将其子进程交给init进程收养。 + + 根据被终止进程的标识符,从$PCB$集合中找到终止进程的$PCB$,读取进程的状态。 + + 若进程正在运行,则立刻剥夺其$CPU$交给其他进程。 + + 若是普通的终止,父进程终止时会将其子进程交给$init$进程收养。 + 若是整个进程组的进程,则终止其所有子进程。 + 将进程所有的资源交给父进程或操作系统。 - + 删除PCB。 + + 从所在队列或链表中删除$PCB$。 + 引起进程终止的事件: - + 正常结束。 - + 异常结束。 - + 外界干预。 + + 正常结束:任务完成。 + + 异常结束:内部异常,如存储区越界、保护错、运行超时等。 + + 外界干预:外部请求而终止运行,如操作员或操作系统干预、父进程请求、父进程终止。 + 进程阻塞: + 阻塞原语: - + 找到要阻塞的进程对应的PCB。 - + 包含进程运行现场,将PCB状态信息设置为阻塞态,暂停进程。 - + 将PCB插入事件等待队列。 + + 找到要阻塞的进程对应的$PCB$。 + + 保护进程运行现场,将$PCB$状态信息设置为阻塞态,暂停进程。 + + 将$PCB$插入事件等待队列,将处理机资源调度给其他就绪态进程。 + 引起进程阻塞的事件: + 需要等待系统分配资源。 + 需要等待相互合作的其他进程完成工作。 + 进程唤醒: + 唤醒原语: - + 在事件等待队列中找到PCB。 - + 将PCB从等待队列中移除,设置进程为就绪态。 - + 将PCB插入就绪队列,等待被调度。 + + 在事件等待队列中找到$PCB$。 + + 将$PCB$从等待队列中移除,设置进程为就绪态。 + + 将$PCB$插入就绪队列,等待被调度。 + 引起进程唤醒的事件: + 等待的事件的发生(因何事被阻塞因何事被唤醒)。 + 进程切换: + 切换原语: - + 将运行环境信息存入PCB。 - + PCB移入相应队列。 - + 选择另一个进程执行,并更新其PCB。 - + 根据PCB恢复新进程所需的运行环境。 + + 将处理机上下文信息,包括程序计数器$PC$和其他寄存器信息存入$PCB$。 + + $PCB$移入相应队列。 + + 选择另一个进程执行,并更新其$PCB$。 + + 更新内存管理的数据结构。 + + 根据$PCB$恢复新进程所需的运行环境。 + 引起进程切换的事件: + 当前时间片到。 + 有更高优先级进程到达。 + 当前进程主动阻塞。 + 当前进程终止。 -### 进程的通信 +### 进程通信 进程通信是进程之间的信息交换。 -为了保证安全,一个进程不能直接访问另一个进程的地址空间。 +为了保证安全,一个进程不能直接访问另一个进程的地址空间。$PV$操作是低级通信方式,高级通信方式有: -+ 共享存储:分配一个可以共同使用的共享空间,进程对其的使用必须是互斥的。 ++ 共享存储:分配一个可以共同使用的共享空间,进程对其的使用必须是互斥的(使用同步互斥工具如$PV$操作)。 + 基于数据结构:共享空闲只能放固定的数据结构如数组等。速度慢,限制多,是低级通信方式。 + 基于存储取:内存中划出一块共享存储区,数据的形式、存放位置都由进程控制而非操作系统。速度更快,限制少,是高级通信方式。 -+ 管道通信:指用于链接读写进程的一个共享文件,又名pipe文件,其实就是内存中开辟一个大小固定的缓冲区。 - + 只能使用半双工的通信,某一时间段内只能单向传输,若要双向同时通信则必须设置两个管道。 - + 进程需要互斥访问管道。 - + 数据以字符流的形式写入管道,当满时,写进程的write()系统调用将被阻塞,等待读进程将数据取走。当读进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。 - + 如果没有写满则不允许读,如果没有读空则不允许写。 - + 数据一旦被读出就被管道抛弃,所以读进程只能至多有一个,否则可能会读错。 + 信息传递:进程间的数据交换以格式化的消息为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。 - + 消息包括消息头和消息体,消息头包括:发送进程ID、接受进程ID、消息类型、消息长度等格式化的信息。 + + 消息包括消息头和消息体,消息头包括:发送进程$ID$、接受进程$ID$、消息类型、消息长度等格式化的信息。 + 消息传递包括: + 直接通信方式:消息直接挂到接受进程的信息缓冲队列上。 + 间接通信方式:消息先发送到中间实体(信箱)中,因此也称为信箱通信方式,如计算机网络中的电子邮件系统。 ++ 管道通信:是消息传递的特殊方式,指用于链接各自一个的读写进程的一个共享文件,又名$pipe$文件,其实就是内存中开辟一个大小固定的缓冲区。 + + 只能使用半双工的通信,某一时间段内只能单向传输,若要双向同时通信则必须设置两个管道。 + + 进程需要互斥访问管道,需要满足互斥、同步、确定对方存在。 + + 数据以字符流的形式写入管道,当满时,写进程的$write()$系统调用将被阻塞,等待读进程将数据取走。当读进程将数据全部取走后,管道变空,此时读进程的$read()$系统调用将被阻塞。 + + 如果没有写满则不允许读,如果没有读空则不允许写。 + + 数据一旦被读出就被管道抛弃,所以读进程只能至多有一个,否则可能会读错。 ### 线程 -#### 线程的概念 +#### 线程概念 传统而看,进程是程序的一次执行,但是程序的多个功能不能由一个程序顺序处理就能完成,所以一个进程需要同时进行多个任务,所以就引入了线程来增加并发度。 -线程是基本的CPU执行单元,是程序执行流的最小单位。进程只作为除CPU之外的系统资源的分配单元,即打印机等都是分配给进程而不是线程。 +由线程$ID$、程序计数器$PC$、寄存器集合和堆栈组成。 -#### 进入线程的变化 +线程是基本的$CPU$执行单元,是程序执行流的最小单位,是处理机的分配单元。进程只作为除$CPU$之外的系统资源的分配单元,即打印机等都是分配给线程而不是进程。 + +#### 线程与进程 + 系统分配调度: + 传统进程机制中,进程是资源分配、调度的基本单位。 + 引入线程后,进程是资源分配的基本单位,线程是调度的基本单位。 + + 同一进程中,线程切换不会导致进程切换,在不同进程进行线程切换才会引起进程切换。 ++ 拥有资源: + + 进程都是拥有资源的基本单位,线程除了必备的资源不拥有系统资源。 + + 线程可以拥有同进程的所有资源。 + 并发性: + 传统进程机制中,只能进程间并发。 + 引入线程后,各线程间也能并发,提升了并发度。 @@ -184,29 +211,35 @@ + 传统的进程间并发,需要切换进程的运行环境,系统开销很大。 + 线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小。 + 引入线程后,并发所带来的系统开销减小。 + + 同一进程多个线程共享进程地址空间,所以线程同步通信非常容易。 ++ 地址空间和其他资源: + + 进程间不可见,同一进程的线程间可见。 ++ 通信: + + 进程间通信$IPC$需要进程同步和互斥来保证一致性。 + + 线程间可以直接读写进程数据段如全局变量完成。 -#### 线程的属性 +#### 线程属性 + 线程是处理机调度的单位。 -+ 多CPU计算机中,各个线程可占用不同的CPU。 -+ 每个线程都有一个线程ID、线程控制块(TCB)。 ++ 多$CPU$计算机中,各个线程可占用不同的$CPU$。 ++ 每个线程都有一个线程$ID$、线程控制块$TCB$(记录线程执行的寄存器和栈等现场状态)。 + 线程也有就绪、阻塞、运行三种基本状态。 + 线程几乎不拥有系统资源。 + 同一进程的不同线程间共享进程的资源。 -+ 由于共享内存地址空间,同-进程中的线程间通信甚至无需系统干预。 ++ 由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预。 + 同一进程中的线程切换,不会引起进程切换。 + 不同进程中的线程切换,会引起进程切换。 + 切换同进程内的线程,系统开销很小。 + 切换进程,系统开销较大。 -#### 线程的实现 +#### 线程实现 -+ 用户级线程: ++ 用户级线程$ULT$: + 用户级线程由应用程序通过线程库实现。所有的线程管理工作都由应用程序负责(包括线程切换)。 + 用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。 + 在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。用户级线程对用户不透明,对操作系统透明。 + “ 用户级线程”就是“从用户视角看能看到的线程”。 -+ 内核级线程(内核支持的线程): ++ 内核级线程(内核支持的线程)$KLT$: + 内核级线程的管理工作由操作系统内核完成。 + 线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。 + “内核级线程” 就是“从操作系统内核视角看能看到的线程”。 @@ -239,12 +272,12 @@ + 高级调度(作业调度): + 由于内存空间有限,有时无法将用户提交的作业全部放入内存,因此就需要确定某种规则来决定将作业调入内存的顺序。一般一个作业包含多个进程。 - + 高级调度按一定的原则从外存上处于后备队列的作业中挑选一个(或多个)作业,给他们分配内存等必要资源,并建立相应的进程(建立PCB),以使它(们)获得竞争处理机的权利。 - + 高级调度是辅存(外存)与内存之间的调度。每个作业只调入一次,调出一次。作业调入时会建立相应的PCB,作业调出时才撤销PCB。 + + 高级调度按一定的原则从外存上处于后备队列的作业中挑选一个(或多个)作业,给他们分配内存等必要资源,并建立相应的进程(建立$PCB$),以使它(们)获得竞争处理机的权利。 + + 高级调度是辅存(外存)与内存之间的调度。每个作业只调入一次,调出一次。作业调入时会建立相应的$PCB$,作业调出时才撤销$PCB$。 + 高级调度主要是指调入的问题,因为只有调入的时机需要操作系统来确定,但调出的时机必然是作业运行结束才调出。 + 中级调度(内存调度): + 引入了虚拟存储技术之后,可将暂时不能运行的进程调至外存等待。等它重新具备了运行条件且内存又稍有空闲时,再重新调入内存。这么做的目的是为了提高内存利用率和系统吞吐量。 - + 暂时调到外存等待的进程状态为挂起状态。值得注意的是,PCB并不会一起调到外存,而是会常驻内存。PCB中会记录进程数据在外存中的存放位置,进程状态等信息,操作系统通过内存中的PCB来保持对各个进程的监控、管理。被挂起的进程PCB会被放到的挂起队列中。 + + 暂时调到外存等待的进程状态为挂起状态。值得注意的是,$PCB$并不会一起调到外存,而是会常驻内存。$PCB$中会记录进程数据在外存中的存放位置,进程状态等信息,操作系统通过内存中的$PCB$来保持对各个进程的监控、管理。被挂起的进程$PCB$会被放到的挂起队列中。 + 中级调度就是要决定将哪个处于挂起状态的进程重新调入内存。 + 一个进程可能会被多次调出、调入内存,因此中级调度发生的频率要比高级调度更高。 + 低级调度(进程调度): @@ -256,7 +289,7 @@ :----:|:------:|:-----:|:-----:|:-------------: 高级调度(作业调度)|按照某种规则,从后备队列中选择合适的作业将其调入内存,并为其创建进程|外存→内存(面向作业)|一个作业一个调入一次调出|无→创建态→就绪态 中级调度(内存调度)|按照某种规则,从挂起队列中选择合适的进程将其数据调回内存|外存→内存(面向进程)|中等|挂起态→就绪态(阻塞挂起→阻塞态) -低级调度(进程调度)|按照某种规则,从就绪队列中选择一个进程为其分配处理机|内存→CPU|最高|就绪态→运行态 +低级调度(进程调度)|按照某种规则,从就绪队列中选择一个进程为其分配处理机|内存→$CPU$|最高|就绪态→运行态 ### 进程调度 @@ -281,11 +314,11 @@ + 进程在操作系统**内核程序临界区**中。 + 临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源。 + 临界区:访问临界资源的那段代码。 - + 内核程序临界区一般是用来访问某种内核数据结构的,比如进程的就绪队列(由各就绪进程的PCB组成)。 + + 内核程序临界区一般是用来访问某种内核数据结构的,比如进程的就绪队列(由各就绪进程的$PCB$组成)。 + 进程访问时会上锁,而如果还没退出临界区(还没解锁)就进行进程调度但是进程调度相关的程序也需要访问就绪队列,但此时就绪队列被锁住了,因此无法顺利进行进程调度。 + 内核程序临界区访问的临界资源如果不尽快释放的话,极有可能影响到操作系统内核的其他管理工作。因此在访问内核程序临界区期间不能进行调度与切换。 - + 而如果是普通程序临界区时,如在打印机打印完成之前,进程一直处于临界区内,临界资源不会解锁。但打印机又是慢速设备,此时如果一直不允许进程调度的话就会导致CPU一直空闲,所以为了保证效率进程在操作系统普通程序临界区时运行进程调度。 -+ 在原子操作过程中(原语)。原子操作不可中断,要一气呵成(如修改PCB中进程状态标志,并把PCB放到相应队列)。 + + 而如果是普通程序临界区时,如在打印机打印完成之前,进程一直处于临界区内,临界资源不会解锁。但打印机又是慢速设备,此时如果一直不允许进程调度的话就会导致$CPU$一直空闲,所以为了保证效率进程在操作系统普通程序临界区时运行进程调度。 ++ 在原子操作过程中(原语)。原子操作不可中断,要一气呵成(如修改$PCB$中进程状态标志,并把$PCB$放到相应队列)。 #### 进程调度的方式 @@ -331,10 +364,10 @@ #### 算法评价指标 -+ CPU利用率:CPU忙碌时间占总时间的比例。其中利用率=忙碌时间÷总时间。 ++ $CPU$利用率:$CPU$忙碌时间占总时间的比例。其中利用率=忙碌时间÷总时间。 + 系统吞吐量:单位时间内完成作业的数量。系统吞吐量=总共完成多少道作业÷总时间。 + 周转时间:从作业被提交到系统开始到作业完成为止的时间间隔。 - + 它包括四个部分:作业在外存后备队列上等待作业调度(高级调度)的时间、进程在就绪队列上等待进程调度(低级调度)的时间、进程在CPU上执行的时间、进程等待I/O操作完成的时间。后三项在一个作业的整个处理过程中,可能发生多次。 + + 它包括四个部分:作业在外存后备队列上等待作业调度(高级调度)的时间、进程在就绪队列上等待进程调度(低级调度)的时间、进程在$CPU$上执行的时间、进程等待I/O操作完成的时间。后三项在一个作业的整个处理过程中,可能发生多次。 + (作业)周转时间=作业完成时间-作业提交时间。 + 平均周转时间=各作业周转时间之和÷作业数。 + 带权周转时间=作业周转时间÷作业实际运行的时间=(作业完成时间-作业提交时间)÷作业实际运行的时间(≥1)。 @@ -342,7 +375,7 @@ + 等待时间:指进程或作业处于等待处理机状态时间之和。 + 对于进程来说,等待时间就是指进程建立后等待被服务的时间之和,在等待I/O完成的期间其实进程也是在被服务的,所以不计入等待时间。 + 对于作业来说,不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间。 - + 一个作业总共需要被CPU服务多久,被I/O设备服务多久一般是确定不变的,因此调度算法其实只会影响作业或进程的等待时间。当然,与前面指标类似,也有“平均等待时间”来评价整体性能。 + + 一个作业总共需要被$CPU$服务多久,被I/O设备服务多久一般是确定不变的,因此调度算法其实只会影响作业或进程的等待时间。当然,与前面指标类似,也有“平均等待时间”来评价整体性能。 + 如果一个进程到达后要么等待要么运行,则等待时间=周转时间-运行时间。 + 如果一个进程又有计算又有I/O操作,则等待时间=周转时间-运行时间-I/O操作时间。 + 响应时间:从用户提交请求到首次产生响应所用的时间。 @@ -458,7 +491,7 @@ P4|5|4 + 算法思想:公平地、轮流地为各个进程服务,让每个进程在一定时间间隔内都可以得到响应。 + 算法规则:按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片(如100ms)。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队。 + 用于作业/进程调度:用于进程调度(只有作业放入内存建立了相应的进程后,才能被分配处理机时间片)。 -+ 是否可抢占:若进程未能在时间片内运行完,将被强行剥夺处理机使用权,因此时间片轮转调度算法属于抢占式的算法。由时钟装置发出时钟中断来通知CPU时间片已到。 ++ 是否可抢占:若进程未能在时间片内运行完,将被强行剥夺处理机使用权,因此时间片轮转调度算法属于抢占式的算法。由时钟装置发出时钟中断来通知$CPU$时间片已到。 + 优缺点: + 优点: + 公平。 @@ -532,7 +565,7 @@ P4|5|4 + 设置进程优先级: + 系统进程高于用户进程。 + 前台进程高于后台进程。 - + 操作系统更偏好I/O型进程(I/O繁忙型进程)而不是计算型进程(CPU繁忙型进程),I/O设备和CPU可以并行工作。如果优先让I/O繁忙型进程优先运行的话,则越有可能让I/O设备尽早地投入工作,则资源利用率、系统吞吐量都会得到提升。 + + 操作系统更偏好I/O型进程(I/O繁忙型进程)而不是计算型进程($CPU$繁忙型进程),I/O设备和$CPU$可以并行工作。如果优先让I/O繁忙型进程优先运行的话,则越有可能让I/O设备尽早地投入工作,则资源利用率、系统吞吐量都会得到提升。 + 调整动态优先级: + 若进程在就绪队列中等待了很长时间,则提升其优先级。 + 若进程占用处理机很长时间,则降低其优先级。 @@ -593,7 +626,7 @@ P4|5|4|2 + 每个新到达的进程都可以很快就得到响应(RR的优点)。 + 短进程只用较少的时间就可完成(SPF的优点)。 + 不必实现估计进程的运行时间(避免用户作假)。 - + 可灵活地调整对各类进程的偏好程度,比如CPU密集型进程、I/O密集型进程(拓展:可以将因I/O而阻塞的进程重新放回原队列,这样I/O型进程就可以保持较高优先级) + + 可灵活地调整对各类进程的偏好程度,比如$CPU$密集型进程、I/O密集型进程(拓展:可以将因I/O而阻塞的进程重新放回原队列,这样I/O型进程就可以保持较高优先级) + 是否会导致饥饿:会。 **例题** 各进程到达就绪队列的时间、需要的运行时间如下表所示。使用多级反馈队列调度算法,分析进程运行状态。 @@ -855,7 +888,7 @@ lock = false; // "解锁"" + 适用于多处理机环境。 + 缺点: + 不满足“让权等待”原则。 - + 暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从而导致“忙等”。 + + 暂时无法进入临界区的进程会占用$CPU$并循环执行TSL指令,从而导致“忙等”。 #### Swap指令 @@ -890,7 +923,7 @@ lock = false; + 适用于多处理机环境 + 缺点: + 不满足“让权等待”原则。 - + 暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从而导致“忙等”。 + + 暂时无法进入临界区的进程会占用$CPU$并循环执行TSL指令,从而导致“忙等”。 ### 信号量机制 @@ -1512,7 +1545,7 @@ Pi() { #### 死锁发生的情况 -1. 对系统资源的竞争。各进程对不可剥夺的资源(如打印机)的竞争可能引起死锁,对可剥夺的资源(CPU)的竞争是不会引起死锁的。 +1. 对系统资源的竞争。各进程对不可剥夺的资源(如打印机)的竞争可能引起死锁,对可剥夺的资源($CPU$)的竞争是不会引起死锁的。 2. 进程推进顺序非法。请求和释放资源的顺序不当,也同样会导致死锁。例如,并发执行的进程P1、P2分别申请并占有了资源R1、R2,之后进程P1又紧接着申请资源R2,而进程P2又申请资源R1,两者会因为申请的资源被对方占有而阻塞,从而发生死锁。 3. 信号量的使用不当也会造成死锁。如生产者-消费者问题中,如果实现互斥的P操作在实现同步的Р操作之前,就有可能导致死锁。(可以把互斥信号量、同步信号量也看做是一种抽象的系统资源) @@ -1544,7 +1577,7 @@ Pi() { 该策略的缺点: 1. 实现起来比较复杂。 -2. 释放已获得的资源可能造成前一阶段工作的失效。因此这种方法一般只适用于易保存和恢复状态的资源,如CPU。 +2. 释放已获得的资源可能造成前一阶段工作的失效。因此这种方法一般只适用于易保存和恢复状态的资源,如$CPU$。 3. 反复地申请和释放资源会增加系统开销,降低系统吞吐量。 4. 若采用方案一,意味着只要暂时得不到某个资源,之前获得的那些资源就都需要放弃,以后再重新申请。如果一直发生这样的情况,就会导致进程饥饿。