第1章 导论
1.描述操作系统的概念,解释说明其主要作用。
操作系统是控制和管理整个计算机系统的硬件与软件资源,合理地组织、调度计算机的工作与资源的分配,进而为用户和其他软件提供方便接口与环境的程序集合。
操作系统是计算机系统中最基本的系统软件。
2.请结合操作系统对资源和程序的管理和分配,阐述中断的作用?
发生了中断,就意味着需要操作系统介入,开展管理工作。
由于操作系统的管理工作(比如进程切换、分配I/O设备等)需要使用特权指令,因此CPU要从用户态转为核心态。中断可以使CPU从用户态切换为核心态,使操作系统获得计算机的控制权。有了中断,才能实现多道程序并发执行,提高CPU利用率。
第2章 操作系统结构
1.试描述操作系统的启动过程。
操作系统启动过程分为四部:BIOS自检、系统引导、启动内核、初始化系统。
(1)BIOS自检:在计算机开机时,boot被自动执行,指引CPU把操作系统从大容量存储器中传送到主存储器的易失区。
(2)系统引导:将系统内核从外存读入内存,并将其放在合适的位置中。
(3)启动内核:当处理器离开引导程序的时候,从实模式跳转到保护模式解压内核镜像。
(4)初始化系统:在内存中的为内存镜像,需要进行解压,解压后需要把内核放在适当的位置。进入保护模式的系统初始化了。
第3章 进程
1.描述进程的概念,进程与程序有何区别?画出进程的状态转换图,并分析状态转换的时机或场合。
(1)进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。
(2)程序本身不是进程,程序只是被动实体,而进程是活动实体。当一个可执行文件被装入内存时,一个程序才能成为进程。
(3)进程的五个状态:新建(new),就绪(ready),运行(running),等待/阻塞(waiting),终止(terminated)。
(4)基本状态之间的转换如下:
新建态->就绪态:进程获得了除处理机外的一切所需资源时,进程由新建态转换为就绪态。
就绪态->运行态:处于就绪态的进程被调度后,获得处理机资源(分派处理机时间片),进程就由就绪态转换为运行态。
运行态->就绪态:处于运行态的进程在时间片用完或有更高优先级的进程就绪时,不得不让出处理机,从而进程由运行态转换为就绪态。
运行态->等待态:进程请求某一资源(如外设)的使用和分配或等待某一事件的发生(如I/O操作的完成)时,它就从运行态转换为等待态。
等待态->就绪态:进程等待事件到来时,如中断结束时,中断处理程序必须把相应的进程的状态由等待态转换为就绪态。
运行态->终止态:当进程正常结束或由于其他原因中断退出运行时,系统将进程的状态由运行态转换为终止态,然后进一步处理资源释放和回收等工作。
2.描述进程间通信的两种方式:消息传递和共享内存,并说明其优缺点和适用场合。
(1)消息传递
在信息传递系统中,进程间的数据交换是以格式化的信息为单位的。进程通过系统提供的发送信息和接收信息两个原语进行数据交换。
(2)共享内存
在通信的进程之间存在一块可直接访问的共享空间,通过对这片共享空间进行写/读操作来实现进程之间的信息交换。使用同步互斥工具(如P操作、V操作)对共享空间的写/读进行控制。
(3)消息传递与共享内存的比较
消息传递对于交换较少数量的数据很有用,因此不需要避免冲突。
共享内存允许以最快的速度进行方便的通信,在计算机中它可以达到内存的速度。
消息传递比共享内存更易于实现。
消息传递系统通常用系统调用来实现,因此需要更多的内核介入的时间消耗。共享内存仅在建立共享内存区域时需要系统调用。
3.画出进程NEW、READY、RUNNING、WAITING、TERMINATED的状态图,并说明状态之间变换的原因。
参考第1题
第4章 线程
1.操作系统中为什么要引入线程?
(引入进程的目的是更好地使多道程序并发执行,提高资源利用率和系统吞吐量。)
引入线程的目的是减少程序在并发执行时所付出的时空开销,提高操作系统的并发性能。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,它可与同属一个进程的其他线程共享进程所拥有的全部资源。
第5章 CPU调度
1.考虑下面一组进程,进程占用的CPU区间长度以毫秒来计算:
进程 区间时间 优先级
P1 10 3
P2 1 1
P3 2 3
P4 1 4
P5 5 2
假设在0时刻进程以P1, P2, P3, P4, P5的顺序到达。(规定小数字表示高优先级)
对于下面4种调度算法,分别给出进程调度的甘特(Gantt)图,并计算每个进程的周转时间、等待时间和平均等待时间。(高频率,10分左右)
a.FCFS 先到先服务调度算法
b. SJF 最短作业优先调度算法
c. PRIORITY 优先级调度算法(非抢占)
d. RR 轮转法调度算法(时间片为1)
周转时间=完成时间-提交时间;等待时间=周转时间-运行时间
(1)甘特图如下:
(2)周转时间:
进程 FCFS SJF PRIORITY RR
P1 10 19 16 19
P2 11 1 1 2
P3 13 4 18 7
P4 14 2 19 4
P5 19 9 6 14
(3)等待时间:
进程 FCFS SJF PRIORITY RR
P1 0 9 6 9
P2 10 0 0 1
P3 11 2 16 5
P4 13 1 18 3
P5 14 4 1 9
(4)平均等待时间:
进程 FCFS SJF PRIORITY RR
平均等待时间 9.6 3.2 8.2 5.4
2.简要描述进程调度中多级反馈队列调度算法的基本思想。
多级反馈调度算法允许进程在队列之间移动。
主要思想是根据不同CPU区间的特点以区分进程。如果进程使用过多CPU时间,那么它会被转移到更低优先级队列。
这种方案将I/O约束和交互进程留在更高优先级队列,在较低优先级队列中等待时间过长的进程会被转移到更高优先级队列。这种形式的老化阻止饥饿的发生。
多级反馈队列调度程序的定义使它成为最通用的CPU调度算法,它也是最复杂的算法。
3.衡量进程调度算法性能的指标有哪些?
(1)CPU利用率:利用率=忙碌的时间/总时间
(2)系统吞吐量:单位时间内完成的作业数量
(3)周转时间:周转时间=作业完成时间-作业提交时间
平均周转时间=各作业周转时间之和/作业数
带权周转时间=作业周转时间/作业实际运行的时间
平均带权周转时间=各作业带权周转时间之和/作业数
对于周转时间相同的两个作业,实际运行时间长的作业在相同时间内被服务的时间更多,带权周转时间更小,用户满意度更高。
对于实际运行时间相同的两个作业,周转时间短的带权周转时间更小,用户满意度更高。
(4)等待时间:指作业/进程处于等待处理机状态时间之和。
平均等待时间是各个进程/作业等待时间的平均值。
一个作业总共需要被CPU服务多久,被I/O设备服务多久一般是确定不变的,因此调度算法其实只能影响作业或者进程的等待时间。“平均等待时间”来评价整体性能。
(5)响应时间:指从用户提交请求到首次产生响应所用的时间。
4.试列举3种常见的进程调度算法,并描述其基本思想,说明其优缺点。
(1)FCFS 先到先服务调度算法
先请求CPU的进程先分配到CPU,FCFS策略可以用FIFO队列来实现。
FCFS调度的代码编写简单且容易理解。
采用FCFS策略的平均等待时间通常较长。
(2)SJF 最短作业优先调度算法
SJF调度算法将每个进程与其下一个CPU区间段相关联。当CPU空闲时,它会赋给具有最短CPU区间的进程。如果两个进程具有同样长度,使用FCFS调度来处理。
SJF算法的平均等待时间最小。
SJF算法的困难是如何知道下一个CPU区间的长度。(近似SJF调度)
(3)抢占SJF调度算法(最短剩余时间调度算法, SRTF)
当一个新进程到达就绪队列而以前进程正在执行时,就需要选择。与当前运行的进程相比,新进程可能有一个更短的CPU区间。
抢占SJF算法可抢占当前运行的进程,而非抢占SJF算法会允许当前运行的进程先完成其CPU区间。
(4)优先级调度算法
每个进程都有一个优先级与其关联,具有最高优先级的进程会分配到CPU。具有相同优先级的进程按FCFS顺序调度。
优先级调度算法的一个主要问题是饥饿(无穷阻塞),可以运行但缺乏CPU的进程可认为是阻塞的,它在等待CPU。优先级调度算法会是某个低优先级进程无穷地等待CPU。
解决饥饿的方法之一是老化。老化是一种技术,以逐渐增加在系统中等待很长时间的进程的优先级。
(5)抢占优先级调度算法
当一个进程到达就绪队列时,其优先级与当前运行进程的优先级相比较。如果新到达进程的优先级高于当前运行进程的优先级,那么抢占优先级调度算法会抢占CPU。而非抢占优先级调度算法只是将新进程加到就绪队列的头部。
(6)RR 轮转法调度算法
RR调度算法是专门为分时系统设计的。它类似于FCFS调度,但增加了抢占以切换进程。定一个较小的时间单元,称为时间片。将就绪队列作为循环队列。CPU调度程序循环就绪队列,为每个进程分配不超过一个时间片的CPU。
RR算法的性能很大程度上依赖于时间片的大小。
(7)多级队列调度算法
将就绪队列分成多个独立队列。根据进程的属性,一个进程被永久地分配到一个队列,每个队列有自己的调度算法。队列之间必须有调度,通常采用固定优先级抢占调度。
(8)多级反馈队列调度算法
多级反馈调度算法允许进程在队列之间移动。主要思想是根据不同CPU区间的特点以区分进程。如果进程使用过多CPU时间,那么它会被转移到更低优先级队列。
5.抢占SJF(SRTF)的调度题目
见智库
第6章 进程同步
1.信号量及PV操作编程题(伪代码,推荐类C代码;100%出现)
2.什么是读者-写者问题?利用信号量写出解决读者/写者问题的同步程序。
(1)读者-写者问题:
有读者和写者两组并发进程,共享一个文件。当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。
(2)程序
semaphore rw = 1; //用于实现对共享内存的互斥访问
int count = 0; //用于记录当前有几个进程正在访问文件
semaphore mutex = 1; //用于保证对于count变量的互斥访问
semaphore w = 1; //用于实现"读写公平"
写进程:
writer( ){
while(1){
P(w);
P(rw);
写文件…
V(rw);
V(w);
}
}
读进程:
reader( ){
while(1){
P(w);
P(mutex);
if(count == 0)
P(rw);
V(mutex);
V(w);
读文件…
P(mutex);
count–;
if(count == 0)
V(rw);
V(mutex);
}
}
3.解释说明临界区(Critical Section),及其解决方案所需要满足的几个条件。
(1)假设某个系统有n个进程,每个进程有一个代码段称为临界区,在该区中进程可能改变共同变量、更新一个表、写一个文件等。当一个进程进入临界区,没有其他进程可被允许在临界区执行,即没有两个进程可同时在临界区内执行。
临界区问题是设计一个以便进程协作的协议。每个进程必须请求允许进入其临界区。
(2)临界区问题的解答必须满足如下三项要求:
【1】互斥:没有两个进程可同时在临界区内执行。
【2】前进:如果没有进程在其临界区内执行且有进程需进入临界区,那么只有那些不在剩余区内执行的进程可参加选择,以确定谁能下一个进入临界区,且这种选择不能无限推迟。
【3】有限等待:从一个进程做出进入临界区的请求,直到该请求允许为止,其他进程允许进入其临界区的次数有上限。
4.解决临界区问题需要遵循的准则有哪些?从进程同步的角度描述生产者与消费者问题。
(1)临界区问题的解答必须满足如下的三项要求:
【1】互斥:当已有进程进入临界区时,其他试图进入临界区的进程必须等待。
【2】前进:临界区空闲时,可允许一个进程进入临界区的进程立即进入临界区。
【3】有限等待:对请求访问的进程,应保证能在有限时间内进入临界区。(保证不会饥饿)
(2)描述生产者与消费者问题
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。
生产者、消费者共享一个初始为空、大小为n的缓冲区。缓冲区是临界资源,各进程的必须互斥地访问。
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。
只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。
5.甲乙丙三人疫情结束后一起聚餐,吃完饭后,三人一起看电影,用伪代码写出三人一起行动的过程,并且要防止死锁的发生。
参考答案1:
#define N 3 // 人数
semaphore mutex_dinner = 1;
int count_dinner = 0;
semaphore barrier_dinner = 0;
semaphore mutex_ film = 1;
int count_ film = 0;
semaphore barrier_ film = 0;
proc() // 甲乙丙三人,每人一个进程
{
wait(mutex_dinner);
count_dinner = count_dinner + 1;
signal(mutex_dinner);
if(count_dinner == N) // 我是最后到达饭店的
signal(barrier_dinner); // 唤醒比自己早到饭店的另外的人之一
wait(barrier_dinner); // 等待唤醒
signal(barrier_dinner); // 被唤醒后,负责唤醒另一人
dine_together(); //一起吃饭
go_to_the_cinema(); // 分别前往电影院。分别行动,到达的时间很可能不同
wait(mutex_ film);
count_ film = count_ film + 1;
signal(mutex_ film);
if(count_ film == N) // 我是最后到达电影院的
signal(barrier_ film); // 唤醒比自己早到电影院的另外的人之一
wait(barrier_ film);
signal(barrier_ film); // 被唤醒后,负责唤醒另一人
watch_a_film_together ();
}
参考答案2:
#define N 3 // 人数
semaphore mutex_dinner = 1;
int count_dinner = 0;
semaphore barrier_dinner = 0;
semaphore mutex_ film = 1;
int count_ film = 0;
semaphore barrier_ film = 0;
proc() // 甲乙丙三人,各一个进程
{
int i;
wait(mutex_dinner);
count_dinner = count_dinner + 1;
signal(mutex_dinner);
if(count_dinner == N) { // 我是最后到达饭店的
for(i = 0; i < N – 1; i++)
signal(barrier_dinner); // 依次唤醒比自己早到饭店的人
}
else
wait(barrier_dinner); // 不是最后到达饭店的,先休息会
dine_together();
go_to_the_cinema(); // 分别前往电影院。分别行动,到达的时间很可能不同
wait(mutex_ film);
count_ film = count_ film + 1;
signal(mutex_ film);
if(count_ film == N) { // 我是最后到达电影院的
for(i = 0; i < N – 1; i++)
signal(barrier_ film); // 依次唤醒比自己早到电影院的人
}
else
wait(barrier_ film); // 不是最后到达电影院的,先休息会
watch_a_film_together ();
}
6.描述信号量的数据结构,给出信号量中P操作和V操作的过程描述。
7.有一个食堂,最多容许200人同时就餐。食堂仅有一个门,该门可以同时进出三个人。试分析就餐者之间的同步关系,并用P、V操作描述之。
8.从前有座山,山上有座庙,山下有口井。庙里小和尚需要挑水。有人舞担,有人拿桶,有人诵挑水秘诀。挑水时,三个和尚必须一人持担,一人拿桶、一人诵挑水秘诀(同时进行)后方能挑水。每个和尚都是先喜欢诵诀,其次持担、其次持桶。请写出信号量和相关伪代码。
semaphore s_songjue = 1; // 抢夺诵诀的信号量
semaphore s_chidan = 1; // 抢夺持担的信号量
int i_songjue = 0; // 记录哪个和尚抢得诵诀,0表示尚未有和尚抢得
int i_chidan = 0; // 记录哪个和尚抢得持担,0表示尚未有和尚抢得
semaphore s_sync = 0; // 抢得诵诀与抢得持担的2个和尚等待持桶的和尚
monk(i) // i = 1, 2, 3 为和尚的号码
{
P(s_songjue); // 抢得诵诀,或阻塞
if(i_songjue == 0) { // 0表示尚未有和尚抢得
i_songjue = i; // 标记本和尚抢得
V(s_songjue); // 唤醒另外一个抢诵诀的和尚
V(s_songjue); // 唤醒另外一个抢诵诀的和尚
P(s_sync); // 等待持桶的和尚
songjue();
}
else { // 没有抢得诵诀,转而抢持担
P(s_chidan); // 抢得持担,或阻塞
if(i_chidan == 0) { // 0表示尚未有和尚抢得
i_chidan = i; // 标记本和尚抢得
V(s_chidan); // 唤醒另外一个抢持担的和尚
P(s_sync); // 等待持桶的和尚
chidan();
}
else {
V(s_sync); // 通知诵诀或持担的和尚之一,自己已准备好持桶
V(s_sync); // 通知诵诀或持担的和尚之一,自己已准备好持桶
chitong();
}
}
}
第7章 死锁
1.系统有五个进程(P0~P4),三种资源(A,B,C),在T0时刻的快照如下:
进程 Allocation Request Available
A B C A B C A B C
P0 0 1 0 0 0 0 0 0 0
P1 2 0 0 2 0 2
P2 3 0 3 0 0 0
P3 2 1 1 1 0 0
P4 0 0 2 0 0 2
(1)应用死锁检测算法,检测该状态有无死锁?如有,是那些进程?(中高频,10分左右)
Work = Available = (0,0,0)
进程 Work Request Allocation Work+Allocation
A B C A B C A B C A B C
P0 0 0 0 0 0 0 0 1 0 0 1 0
P2 0 1 0 0 0 0 3 0 3 3 1 3
P3 3 1 3 1 0 0 2 1 1 5 2 4
P1 5 2 4 2 0 2 2 0 0 7 2 4
P4 7 2 4 0 0 2 0 0 2 7 2 6
该状态不处于死锁状态,执行死锁检测算法可以找到一个序列{P0,P2,P3,P1,P4},使得对所有i,Finish[i]=true。
(2)进程P2又请求了资源类型C的一个实例,检测该状态有无死锁?如有,是那些进程?
进程 Allocation Request Available
A B C A B C A B C
P0 0 1 0 0 0 0 0 0 0
P1 2 0 0 2 0 2
P2 3 0 3 0 0 1
P3 2 1 1 1 0 0
P4 0 0 2 0 0 2
进程 Work Request Allocation Work+Allocation
A B C A B C A B C A B C
P0 0 0 0 0 0 0 0 1 0 0 1 0
0 1 0
不存在一个i,使得Pi的Request ≤ Work = (0,1,0)
认为现在系统是死锁。现有的资源并不足以满足其他进程的请求,存在一个包含进程P1, P2, P3和P4的死锁。
2.考虑下面的一个系统在某一时刻的状态:
进程 Allocation Max Available
A B C D A B C D A B C D
P0 0 0 1 2 0 0 1 2 1 5 2 0
P1 1 0 0 0 1 7 5 0
P2 1 3 5 4 2 3 5 6
P3 0 6 3 2 0 6 5 2
P4 0 0 1 4 0 6 5 6
使用银行家算法回答下面的问题:
(1)Need矩阵的内容是怎样的?
Need = Max - Allocation
进程 Need
A B C D
P0 0 0 0 0
P1 0 7 5 0
P2 1 0 0 2
P3 0 0 2 0
P4 0 6 4 2
(2)系统是否处于安全状态?
目前Work向量为(1,5,2,0),将Work向量与Need的各行进行比较,找出比Work小的行。在初始时:
(1,5,2,0) > (0,0,0,0); (1,5,2,0) > (0,0,2,0)
对应进程P0和P3,这里我们选择P0暂时加入安全序列。
释放P0所占的资源(即把P0对应的Allocation的一行与Work向量相加)
Work = (1,5,2,0)+(0,0,1,2)=(1,5,3,2)
Need矩阵更新为
P1 0 7 5 0
P2 1 0 0 2
P3 0 0 2 0
P4 0 6 4 2
在用更新的Work向量和Need矩阵重复上述步骤,得到最终的一个安全序列{P0,P3,P2,P4,P1}。系统处于安全状态。
进程 Work Need Allocation Work+Allocation
A B C D A B C D A B C D A B C D
P0 1 5 2 0 0 0 0 0 0 0 1 2 1 5 3 2
P3 1 5 3 2 0 0 2 0 0 6 3 2 1 11 6 4
P2 1 11 6 4 1 0 0 2 1 3 5 4 2 14 11 8
P4 2 14 11 8 0 6 4 2 0 0 1 4 2 14 12 12
P1 2 14 12 12 0 7 5 0 1 0 0 0 3 14 12 12
(3)如果从进程P1发来一个请求(0,4,2,0),这个请求能否立刻被满足?
Need1 = (0,7,5,0) ≥ (0,4,2,0) = Request1
Available = (1,5,2,0) > (0,4,2,0) = Request1
Available = (1,5,2,0) - (0,4,2,0) = (1,1,0,0)
Allocation1 = (1,0,0,0) + (0,4,2,0) = (1,4,2,0)
Need1 = (0,7,5,0) - (0,4,2,0) = (0,3,3,0)
进程 Work Need Allocation Work+Allocation
A B C D A B C D A B C D A B C D
P0 1 1 0 0 0 0 0 0 0 0 1 2 1 1 1 2
P2 1 1 1 2 1 0 0 2 1 3 5 4 2 4 6 6
P3 2 4 6 6 0 0 2 0 0 6 3 2 2 10 9 8
P1 2 10 9 8 0 0 0 0 1 4 2 0 3 14 11 8
P4 3 14 11 8 0 6 4 2 0 0 1 4 3 14 12 12
P1的请求可以被满足。满足该请求之后可以得到一个安全序列{P0,P2,P3,P1,P4}。
3.什么是饥饿和死锁?说明他们之间有何异同?
(1)死锁:在多道程序系统中,一组进程中的每一个进程都无限期等待被该组进程中的另一个进程所占有且永远不会释放的资源。
(2)饥饿:一个进程长期得不到运行,而处于长期等待的状态。
(3)共同点:两者都是由于竞争资源引起的。
(4)不同点:
【1】从进程状态考虑,死锁进程都处于等待状态,忙等待(处于运行或就绪状态)的进程并非处于等待状态,但却可能被饿死。
【2】死锁进程等待永远不会被释放的资源,饿死进程等待会被释放但却不会分配给自己的资源,表现为等待时限没有上界(排队等待或忙式等待)。
【3】死锁一定发生了循环等待,而饿死则不然。这也表明通过资源分配图可以检测死锁存在与否,但却不能检测是否有进程饿死;
【4】死锁一定涉及多个进程,而饥饿或被饿死的进程可能只有一个。在饥饿的情形下,系统中有至少一个进程能正常运行,只是饥饿进程得不到执行机会。而死锁则可能会最终使整个系统陷入死锁并崩溃。
4.产生死锁的必要条件有哪些?描述死锁预防的基本思想。
(1)死锁产生的必要条件
【1】互斥:至少一个资源必须处于非共享模式,即一次只有一个进程使用。如果另一进程申请该资源,那么申请进程必须等到该资源被释放为止。
【2】占有并等待:一个进程必须占有至少一个资源,并等待另一资源,该资源为其他进程占有。
【3】非抢占:资源不能被抢占,即资源只能在进程完成任务后自动释放。
【4】循环等待:有一组等待进程{P0,P1,…,Pn},P0等待的资源为P1所占有,P1等待的资源为P2所占有,…,Pn-1等待的资源为Pn所占有,Pn等待的资源为P0所占有。
(2)死锁预防的基本思想
设置某些限制条件,破坏产生死锁的4个必要条件中的一个或几个,以防止发生死锁。
5.分析目前系统中是否存在死锁,并说明理由。
有一个环P1->R1->P3->R2->P1
该系统中没有死锁,进程P4可能释放资源类型R2的实例,这个资源可分配给P3,可以打破环。
6.一个场地最多容纳22人,其中有打篮球的(不妨设为活动A),打羽毛球的(不妨设为活动B)。
1)如果人数达到上限则等待
2)如果活动A的人数比活动B的人数多5人,则参与A的同学需等待;如果活动B的人数比活动A的人数多5人,则参与活动B的同学需等待。
3)活动A和活动B的同学可随时离开
请用“参与A”“参与B”“离开A”“离开B”和信号量来说明这个过程。
7.简述死锁预防、死锁避免、死锁检测并比较区别
(1)死锁预防
设置某些限制条件,破坏产生死锁的4个必要条件中的一个或几个,以防止发生死锁。
(2)死锁避免
在资源的动态分配过程中,用某种方法防止系统进入不安全状态,从而避免死锁。
(3)死锁检测
无需采取任何限制性措施,允许进程在运行过程中发生死锁。通过系统的检测机构及时地检测出死锁的发生,然后采取某种措施解除死锁。
第8章 内存管理
1.一个进程的页表见下面的表格。页的大小为1024字节。为执行命令MOV AX, [2560]和MOV BX, [4098],计算逻辑地址2560和4098对应的物理地址。(中低频,10分左右)
页号 帧号
0 20
1 30
2 18
3 80
注:题目中所有数字均为10进制,2560和4098在真题中均为4位10进制数。
AX及BX均为寄存器名,MOV为移动数据的汇编指令。注意地址是否有溢出?
(1)MOV AX, [2560]
页号为2560/1024=2,页内偏移量为2560%1024=512
由表格可知,页号2对应帧号18
物理地址为18*1024+512=18944
(2)MOV BX, [4098]
页号为4098/1024=4,页内偏移量为4098%1024=2
由于页号4>=页表长度4,页表中没有4号页,所以地址溢出。
2.简述页式管理和段式管理的地址映射过程。
(1)页式管理
【1】根据逻辑地址计算出页号、页内偏移量
【2】判断页号是否越界
【3】查询页表,找到页号对应的页表项,确定页面存放的内存块号
【4】用内存块号和页内偏移量得到物理地址
【5】访问目标内存单元
(2)段式管理
【1】根据逻辑地址计算出段号、段内地址
【2】判断段号是否越界
【3】查询段表,找到段号对应的段表项
【4】检查段内地址是否超过段长,若段内地址≥段长,则产生越界中断;否则继续执行,确定段号对应的段基址
【5】用段基址和段内地址计算得到物理地址
【6】访问目标内存单元
3.在某个采用页式存储管理系统中,某作业有4个页面,被装入到主存的第3, 4, 6, 8块中。假定页面和存储块的大小均为1024字节,主存容量为10K字节。
当该作业执行到地址空间第500号处遇到一条传送指令MOV 2100, 3100,请用地址变换图计算出该指令中两个操作数的物理地址。
根据题意,页表如下:
页号 帧号
0 3
1 4
2 6
3 8
(1)2100
页号为2100/1024=2,页内偏移量为2100%1024=52
页号2对应的帧号为6,物理地址为61024+52=6196
(2)3100
页号为3100/1024=3,页内偏移量为3100%1024=28
页号3对应的帧号为8,物理地址为81024+28=8220
4.请图示说明在页式存储管理系统中对页面共享的方法,并说明共享代码与共享数据有何限制条件。(参考OSC7 图8.13)
(1)页面共享的方法:
多个进程共享一个相同的页面,只需让各进程的页表项指向同一个页即可实现共享。
(2)共享代码和共享数据的限制条件:
如果共享的代码是可重入代码(纯代码),则可以共享。可重入代码是不能自我修改的代码,它从不会在执行期间改变。
每个进程都有它自己的寄存器副本和数据存储,以控制进程执行的数据。两个不同的进程数据也不同。
在物理内存中保存一个编辑器副本,每个用户的页表映射到编辑器的同一物理副本,而数据页映射到不同的帧。
5.分段和分页,哪一种方法更适合于实现代码共享和信息保护?为什么?
分段比分页更容易实现信息的共享和保护。
(1)代码共享:
在分段方式中,每个段都是逻辑上的一个整体,并且大小不一。只需要让各进程的段表项指向同一个段即可实现共享。
在分页方式中,页面大小是固定的,不是按照逻辑模块划分的,被共享的代码可能在多个页面中,而且一些页面的其他代码可能不允许共享,这就很难利用页表实现共享。
(2)信息保护:
信息保护也是以信息的逻辑单位为基础的。以保护一个函数A为例:
在分段系统中,只需要在包含了函数A的段上标志只读、只写、只执行标志就可以实现。
在分页系统中,函数A可能要占用多个页面,而且其中的第一个和最后一个页面还可能装有其他程序段的数据,它们可能有着不同的保护属性,难以实施统一的保护。
6.逻辑地址和物理地址的绑定(Binding)可以发生在什么时机?各有什么优缺点?
(1)编译时
在编译时就知道进程将在内存中的驻留地址,就可以生成绝对代码。
如果将来开始地址发生变化,那么就必须重新编译代码。
(2)加载时
在编译时并不知道进程将驻留在内存的什么地方,编译器就必须生成可重定位代码,绑定会延迟到加载时才进行。
如果开始地址发生变化,只需重新加载用户代码以引入改变值。
(3)执行时
进程在执行时可以从一个内存段转移到另一个内存段,绑定必须延迟到执行时才进行。
这种方案需要特定的硬件,绝大多数通用计算机操作系统采用这种方法。
7.描述分页内存管理方式的基本思想,给出分页从逻辑地址到物理地址的地址变换过程。
(1)分页内存管理的基本思想:
将物理内存分为固定大小的块,称为帧;将逻辑内存分为同样大小的块,称为页。当需要执行进程时,其页从后备存储(backing store)中调入到可用的内存帧中。后备存储也分为固定大小的块,其大小与内存帧一样。
(2)变换过程:
【1】根据逻辑地址计算出页号、页内偏移量
【2】判断页号是否越界
【3】查询页表,找到页号对应的页表项,确定页面存放的内存块号(帧号)
【4】用内存块号和页内偏移量得到物理地址
【5】访问目标内存单元
8.某系统按字节寻址,逻辑地址结构中,页内偏移量占10位,页号2对应的内存块号b=8,将逻辑地址A=2500转换为物理地址E。
(1)计算页号P和页内偏移量W
P = A/L = 2500/1024 = 2
W = 2500%1024 = 452
(2)由题目条件可知,页号2没有越界,其存放的内存块号b = 8
(3)物理地址E = bL + W = 81024 + 452 = 8644
9. 某磁盘逻辑地址32位,页大小16KB,页表项大小4B
1)采用多层页表结构,该采用几层页表?页偏移多少比特?画出地址分配。
2)对逻辑地址54321(10进制),简述求实际地址的过程(忽略缺页中断)
3)CPU和操作系统在分页中各自承担了那些工作,简要说明
第9章 虚拟内存
1.某程序访问以下页面:7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1
若3个页框(内存块)可用,分别使用下列算法,产生多少次缺页和页面置换?并计算缺页率。(一开始3个页框全空,缺页次数包括填充这些页框的缺页次数)(中频,10分左右)
(1)先进先出(FIFO)置换算法
每次选择淘汰最早进入内存的页面。(借助队列实现)
访问页面 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
内存块1 7 7 7 2 2 2 4 4 4 0 0 0 7 7 7
内存块2 0 0 0 3 3 3 2 2 2 1 1 1 0 0
内存块3 1 1 1 0 0 0 3 3 3 2 2 2 1
是否缺页 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
产生了15次缺页,12次页面置换,缺页率为(15/20)*100%=75%
(2)最优(OPT/MIN)置换算法
每次选择淘汰的页面是以后永不使用或者在最长时间内不再被访问的页面。
访问页面 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
内存块1 7 7 7 2 2 2 2 2 7
内存块2 0 0 0 0 4 0 0 0
内存块3 1 1 3 3 3 1 1
是否缺页 1 1 1 1 1 1 1 1 1
产生了9次缺页,6次页面置换,缺页率为(9/20)*100%=45%
(3)最近最少使用(LRU)置换算法
每次选择淘汰的页面是最近最久未使用的页面。
(访问字段记录该页面自上次被访问以来所经历的时间t。)
(手动做题逆向扫描的最后一个页面就是淘汰的页面。)
访问页面 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
内存块1 7 7 7 2 2 4 4 4 0 1 1 1
内存块2 0 0 0 0 0 0 3 3 3 0 0
内存块3 1 1 3 3 2 2 2 2 2 7
是否缺页 1 1 1 1 1 1 1 1 1 1 1 1
产生了12次缺页,9次页面置换,缺页率为(12/20)*100%=60%
(4)二次机会(时钟)置换算法
为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列。
当某页被访问时,其访问位置为1。(指针不转)
当需要淘汰一个页面时,只需检查页的访问位。如果是0,就选择该页换出(指针转动);如果是1,则将它置为0,暂不换出,继续检查下一个页面(指针转动)。
(需要页面置换时,指针才会动。)
若第一轮扫描中所有页面都是1,则将这些页面的访问位依次置为0后,再进行第二次扫描。
(淘汰一个页面最多会经过两轮扫描)
访问页面 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
内存块1 7 7 7 2 2 4 4 4 3 3 3 0 0 0
内存块2 0 0 0 0 0 2 2 2 1 1 1 7 7
内存块3 1 1 3 3 3 0 0 0 2 2 2 1
是否缺页 1 1 1 1 1 1 1 1 1 1 1 1 1 1
(5)增强型二次机会置换算法
引入(访问位,修改位),修改位=0表示页面没有被修改过,修改位=1表示页面被修改过。
算法规则:将所有可能被置换的页面排成一个循环队列
第一轮:从当前位置开始扫描到第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。
第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0,1)的帧用于替换。本轮将所有扫描过的帧访问位设置为0。
第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0,0)的帧用于替换。本轮扫描不修改任何标准位。
第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0,1)的帧用于替换。
2.一进程指令片段如下表:
指令序号 访存地址(包括指令地址,以逗号分隔的为多地址)16进制
1 F0, E0
2 F4, ED, EA
3 F8
4 FB, EE, ED
5 FE, EB, BA
当前PC指向第一条指令,该进程所有页面都不在内存,分配了2帧,帧号是A和B。帧的大小为16字节。采用局部置换,先进先出的置换算法。给出该进程访问物理内存的物理地址。(中低频,10分左右)
注意:有无陷入无穷循环调页的可能性?
指令序号 物理地址
1 A0, B0
2 A4, BD, BA
3 A8
4 AB, BE, BD
当执行第5条指令时,因为只有2帧,而指令需要3页,将陷入无穷的换页。
注意执行第2条和第4条指令时,虽然也有3个访存地址,但有2个地址是在同一页内。(ED和EA是同一页,EE和ED是同一页)因此不会出现由于帧数不够用陷入无穷的换页的现象。
3.解释系统抖动(thrashing)发生的原因及其解决方法。
4.描述内存抖动(thrashing)发生的原因,并给出一种解决方法。
5.什么是颠簸(抖动, thrashing)?说明采用工作集模型预防系统抖动的思想与过程。(中低频,10分左右)
(1)颠簸/抖动的定义
在页面置换过程中,刚刚换出的页面马上又要换入内存,刚刚换入的页面又要换出内存,这种频繁的页面调度行为称为抖动或颠簸。若一个进程在换页上用的时间多于执行时间,则这个进程就在颠簸。
(2)发生的原因
发生抖动的主要原因是某个进程频繁访问的页面数目高于可用的物理页帧数目。换句话说,分配给进程的物理块不够。
(3)解决方法
(4)采用工作集预防系统抖动的思想与过程
驻留集:指请求分页存储管理中给进程分配的内存块集合。
工作集:指在某段时间间隔内,进程时机访问页面的集合。
基于局部性原理,可以用最近访问过的页面来确定工作集。
工作集模型的原理是,让操作系统跟踪每个进程的工作集,并为进程分配大于其工作集的物理块。落在工作集内的页面需要调入驻留集中,而落在工作集外的页面可从驻留集中换出。若还有空闲物理块,则可以再调一个进程到内存以增加多道程序数。若所有进程的工作集之和超过了可用物理块的总数,则操作系统会暂停一个进程,将其页面调出并将其物理块分配给其他进程,防止出现抖动现象。
6.在一个请求分页系统中,假如一个作业的页面走向为7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3。当分配给该作业的物理块数为3时,试计算当采用LRU页面置换算法时访问过程中所发生的缺页次数和缺页率。(假定开始时内存中的3个块都是空的)
访问页面 7 0 1 2 0 3 0 4 2 3 0 3
内存块1 7 7 7 2 2 4 4 4 0
内存块2 0 0 0 0 0 0 3 3
内存块3 1 1 3 3 2 2 2
是否缺页 1 1 1 1 1 1 1 1 1
缺页次数为9次,缺页率为(9/12)*100%=75%
7.虚拟内存能带来什么好处?当发生缺页时,操作系统如何处理?
(1)虚拟内存的好处
【1】虚拟内存将用户逻辑内存与物理内存分开。在现有物理内存有限的情况下,为程序员提供了巨大的虚拟内存,使编程更加容易。
【2】虚拟内存解决了传统存储管理方式的一次性和驻留性问题。能够运行大作业,提高多道程序并发度,提高内存利用率。
(2)在请求分页系统中,每当所要访问的页面不在内存中,便产生了一个缺页中断,请求操作系统将所缺的页调入内存。此时操作系统将缺页的进程阻塞,若内存中有空闲块,则分配一个块,将要调入的页装入该块,并修改页表中相应的页表项;若此时内存中没有空闲块,则要淘汰某页(若被淘汰页在内存期间被修改过,则要将其写回外存)。
8.当前页表如下:
页号 帧号 Valid/Invalid
0 130 Valid
1 570 Valid
2 -1 Invalid
3 -1 Invalid
页大小为1024字节,该程序分配两个帧,页号0先装入内存。
采用先进先出和局部置换策略,现在访问逻辑地址为3000的字节,问在这个过程中发生了什么主要事件并写出置换后的页表。
页号为3000/1024=2,页内偏移量为3000%1024=952
由于页号为2的页表项对应的有效-无效位为Invalid,说明相关的页未调入到内存。
对标记为无效的页的访问会产生缺页中断,会陷入操作系统。由操作系统的缺页中断处理程序处理中断。
如果内存中有空闲块,则为进程分配一个空闲块,将所缺页面装入该块,并修改页表中相应的页表项。如果内存中没有空闲块,则由页面置换算法选择一个页面淘汰,若该页面在内存期间被修改过,则要将其写回外存。未修改过的页面不用写回外存。
置换后的页表如下:
页号 帧号 Valid/Invalid
0 -1 InValid
1 570 Valid
2 130 Valid
3 -1 Invalid
9.写出下面程序的输出结果,并解释这样输出的原因。
int a = 0;
int main()
{
int pid = fork();
if (pid == 0)
{
a = 2;
print(“child leaving/n”);
}
else
{
wait(NULL);
print(“a=%d/n”. a);
}
}
输出:
child leaving
a=0
原因:
系统调用fork( )是将子进程创建为父进程的复制品。
写时复制技术允许父进程与子进程开始时共享同一页面,这些页面标记为写时复制页,即如果任何一个进程需要对页进行写操作,那么就创建一个共享页的副本。
第10章 文件系统接口
第11章 文件系统实现
1.在文件系统的管理中,当用户访问某文件时,需要给出要访问的文件名,系统根据该文件对应的文件控制块FCB确定该文件在磁盘上的物理位置,然后对文件内容进行存取。
(1)请说明文件系统如何根据用户给出的文件名找到该文件对应的FCB。
(2)在连续、链式、索引三种文件的磁盘块组织方式中,分别说明FCB如何给出文件在磁盘上的物理位置。
(1)FCB(文件控制块)是用来存放控制文件需要的各种信息的数据结构。文件目录是FCB的有序集合,一个FCB就是一个文件目录项。FCB包含了文件的基本信息(文件名、物理地址等),存取控制信息和使用信息。
FCB实现了文件名和文件之间的映射,使用户可以实现“按名存取”。
(2)
【1】连续索引
【2】链式索引
【3】索引分配
用户给出要访问的逻辑块号i,将索引表从外存读入内存,并查找索引表即可知i号逻辑块在外存中的存放位置。
2.描述文件的磁盘空间分配技术(连续、链接及使用FAT的链接、索引),并分析比较各自的优缺点。(中低频,10分左右)
(1)连续分配 (contiguous allocation)
每个文件在磁盘上占有一组连续的块。磁盘地址为磁盘定义了一个线性序列。
一个文件的目录条目包括开始块的地址和该文件所分配区域的长度。
优点:实现简单,存取速度快;作业访问磁盘时需要的寻道数和寻道时间最小。
缺点:只适用于长度固定的文件,不方便文件拓展;会产生外部碎片,磁盘空间利用率低。
(2)链接分配 (linked allocation)
每个文件都是磁盘块的链表,磁盘块可以分布在磁盘的任何地方。
目录包括文件第一块的指针和最后一块的指针。
优点:没有外部碎片,提高了磁盘空间的利用率;可以动态地为文件分配盘块,对文件的增、删、改非常方便。
缺点:只能用于文件的顺序访问,不能支持文件的直接访问;指针需要空间,每个文件需要比原来更多的空间。
使用FAT(文件分配表)的链接分配:每个卷的开始部分用于存储FAT,每块都在该表中有一项,每个表项中存放对应块的下一块链接指针,即下一个盘块号。文件的第一个盘块号记录在目录中,后续的盘块可通过查FAT找到。
FAT表在系统启动时就会被读入内存,查找FAT的过程是在内存中进行的,显著地提高了检索速度,明显减少了访问磁盘的次数。
(3)索引分配 (indexed allocation)
把每个文件的所有的指针(盘块号)放在一起,构成索引块。
每个文件都有其索引块,是一个磁盘块地址的数组。索引块的第i个条目指向文件的第i个块。目录条目包括索引块的地址。要读第i块,通过索引块的第i个条目的指针来查找和读入所需的块。
优点:支持直接访问,没有外部碎片的问题。
缺点:索引块的分配增加了系统存储空间的开销。
3.某磁盘文件区1GiB,每个磁盘块为KiB。
(1)如果空闲存储空间采用位图管理方法,那么位示图需要占用多少个盘块?(列出解题步骤)(中低频,10分左右)
(2)如果采用FAT32,请问FAT表需要几个盘块?
(1)位图利用二进制的一位来表示磁盘中一个盘块的使用情况。
磁盘的总盘块数=230/210=2^20
位图占用的大小=220位,220/23=217B
位图所占盘块数=217/210 = 2^7
(2)FAT32:每32/8=4个字节(B)表示一个项
磁盘的总盘块数=230/210=2^20
FAT项数=磁盘总块数=2^20
FAT长度=FAT项数*4=2^22字节
FAT所占盘块数=222/210=2^12
4.MS-DOS和OS2均采用了FAT磁盘空间分配方式,说明其工作原理。(中低频,5分左右)
参考第2题
5.描述操作系统在执行打开文件open和读文件read时的工作原理,及涉及到的文件系统数据结构。
6.为什么访问文件需要先open( )?以及该操作之后,操作系统产生了什么结构?
(1) open( )操作:
用户给 open( )传入一个文件的逻辑路径名,这时先将该文件系统的目录结构加载进内存,根据文件名,操作系统会首先对系统范围内的打开文件表进行搜索(节省时间)。
如果该文件已经被其他进程打开了,则直接将该进程的打开文件表中的指针指向系统范围打开文件表的这一项,同时,系统打开文件表该文件引用计数加1。
如果该文件在系统范围文件表中不存在,说明该文件第一次打开,则对该文件系统的目录表进行搜索,依次查找到叶结点,叶结点包含了一个该文件控制节点(inode)号,即控制节点的物理位置指针,将这个指针返回给用户,同时在系统范围打开文件表中新注册一行这个文件的信息,将该进程的打开文件表中指针指向这条 新信息,open( )操作的任务就完成了。
(2) read( )操作
通过 open()操作返回的该文件的索引节点号从进程的打开文件表中的指针找到系 统的打开文件表中该文件的 inode(FCB)物理位置指针,将该 FCB 读入内存,通过 FCB 中文件存储类型和存储地址的信息算出数据块的存储地址,将数据块读入即可完成 read( )操作。
7.混合索引,块长为512字节,块号2字节,直接块10个,一级、二级索引块各1个,求最大文件大小。
第12章 大容量存储器系统
1.某磁盘磁道编号为0~199,磁头的当前位置为53,当前的请求队列(按请求的次序)为98,183,37,122,14,124,65,67
按照以下磁盘算法分别计算满足队列中所有I/O请求后的寻道距离。
(1)FCFS
调度顺序:(53),98,183,37,122,14,124,65,67
寻道距离:(183-53)+(183-37)+(122-37)+(122-14)+(124-14)+(124-65)+(67-65)=640
(2)SSTF
调度顺序:(53),65,67,37,14,98,122,124,183
寻道距离:(67-53)+(67-14)+(183-14)=236
(3)SCAN
需要指定磁头移动的方向,这里磁头先朝0方向移动。
调度顺序:(53),37,14,(0),65,67,98,122,124,183
寻道距离:(53-0)+(183-0)=236
(4)C-SCAN
需要指定磁头移动的方向,指定从0移动到199。
调度顺序:(53),65,67,98,122,124,183,(199),(0),14,37
寻道距离:(199-53)+199+(37-0)=382
(5)LOOK
需要指定磁头移动的方向,这里磁头先朝0方向移动。
调度顺序:(53),37,14,65,67,98,122,124,183
寻道距离:(53-14)+(183-14)=208
(6)C-LOOK
需要指定磁头移动的方向,指定从0移动到199的方向。
调度顺序:(53),65,67,98,122,124,183,14,37
寻道距离:(183-53)+(183-14)+(37-14)=322
2.磁盘调度算法有哪几种?说明他们各自的一个主要特点。(中低频,10分左右)
3.说明磁盘调度的基本思想,列举三种磁盘调度算法,说明其优缺点。
(1)FCFS(先来先服务)调度
按请求的顺序,依次进行访问。
优点:算法最公平、简单。
缺点:平均寻道距离大,仅应用在磁盘I/O较少的场合。
(2)SSTF(最短寻道时间优先)调度
从当前磁头位置,寻找寻道时间最短的请求处理。
优点:性能比FCFS调度好。
缺点:不能保证平均寻道时间最短,可能出现"饥饿"现象。
(3)SCAN(elevator, 电梯)调度
磁头在磁盘柱面的两个端点(最小及最大柱面号)之间来回移动,当磁头在某个请求的柱面上方时,就处理该请求。
优点:寻道性能较好,避免了"饥饿"现象。
缺点:不利于远离磁头一端的访问。
(4)C-SCAN调度
磁头从盘面的一个端点移动到另一个端点单向移动,在此过程中,若磁头在某个请求的柱面上方时,就处理该请求;到达另一端点时,立即折返,且在折返的过程中,不处理任何请求。
优点:消除了对两端磁道请求的不公平。
(5)LOOK/C-LOOK调度
在SCAN和C-SCAN调度的基础上,让磁头只移动到一个方向上最远的请求为止,接着马上回头,而不是继续到达磁盘的尽头。
第13章 I/O系统
1.I/O控制有哪几种方式?各有什么特点?
2.描述I/O系统中的轮询机制、中断机制和DMA机制,并说明其优缺点和适用场合。
(1)轮询
思想:计算机从外部设备读取数据到存储器,每次读一个字(或字节)的数据。对读入的每个字,CPU需要对外设状态进行循环检查,直到确定该字已经在I/O控制器的数据寄存器中。
优点:简单,易于实现。
缺点:CPU和I/O设备只能串行工作,CPU需要一直轮询检查,长期处于“忙等”状态,导致CPU的利用率相当低。
(2)中断
思想:允许I/O设备主动打断CPU的运行并请求服务,从而解放CPU,使得其向I/O控制器发送读命令后可以继续做其他游泳的工作。
优点:CPU和I/O设备可以并行工作,提高了CPU利用率。
缺点:数据传输需要经过CPU和频繁的中断处理仍会消耗较多的CPU时间。
(3)DMA(直接内存访问)
思想:在I/O设备和内存之间开辟直接的数据交换通路,彻底解放CPU。
优点:数据传输以“块”为单位,数据传输不需要经过CPU,数据传输效率进一步增加;CPU和I/O设备的并行性得到提升。
缺点:CPU每发出一条I/O指令,只能读/写一个或多个连续的数据块,如果读/写多个离散存储的数据块,需要CPU发出多条I/O指令,进行多次中断处理。
3.现代操作系统允许用户程序直接访问外部设备吗?为什么?这样做有什么好处?
DMA方式 (?)
4.非阻塞和阻塞 I/O 是什么,主要有什么不同,分别用在哪里?
(1)阻塞 I/O,当应用程序发出一个阻塞系统调用时,应用程序挂起,应用程序从运行队列转入等待队列。等系统调用完成之后再回到就绪队列,在合适的时候继续运行。绝大多数操作系统为应用程序提供的都是阻塞系统调用,因为它代码更加简单,更容易理解。
(2)非阻塞 I/O,一个非阻塞调用在程序执行过长时间并不中止应用程序,它会很快返回,其返回值表示已经传输了多少字节。在多个程序协作完成 I/O 的工作时,可能会使用非阻塞 I/O。