1. 线程和进程,怎么实现线程的同步
线程同步机制:
临界区(Critical Section)、互斥量(Mutex)、事件(Event)、信号量(Semaphore)四种方式
1、临界区:又称阻塞,通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
使用临界区域的第一个忠告就是不要长时间锁住一份资源。这里的长时间是相对的,视不同程序而定。对一些控制软件来说,可能是数毫秒,但是对另外一些程序来说,可以长达数分钟。但进入临界区后必须尽快地离开,释放资源。如果不释放的话,会如何?答案是不会怎样。如果是主线程(GUI线程)要进入一个没有被释放的临界区,呵呵,程序就会挂了!临界区域的一个缺点就是:Critical Section不是一个核心对象,无法获知进入临界区的线程是生是死,如果进入临界区的线程挂了,没有释放临界资源,系统无法获知,而且没有办法释放该临界资源。
2、互斥量:采用互斥对象机制。只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享
互斥比较类似阻塞,关键在于互斥可以跨进程的线程同步,而且等待一个被锁住的Mutex可以设定TIMEOUT,不会像Critical Section那样无法得知临界区域的情况,而一直死等。很多只允许应用程序运行一次的实例就是用互斥方法来实现的。当一个互斥对象不再被一个线程所拥有,它就处于发信号状态。此时首先调用waitForsingleobject()的线程就成为该互斥对象的拥有者,此互斥对象设为不发信号状态。当线程调用releaseMutex()并传递一个互斥对象的句柄作为参数时,这种拥有关系就被解除,互斥对象重新进入发信号状态。
3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目, 信号量增加了资源计数的功能,预定数目的线程允许同时进入要同步的代码。
4、事件:通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作
进程通讯机制:
1. 内存映射文件(Memory-MappedFiles)
能使进程把文件内容当作进程地址区间一块内存那样来对待, 进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。
2. 共享内存(Shared Memory)
实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用文件映射实现的,所以它也有较好的安全性,也只能运行于同一计算机上的进程之间。
3. 管道(Pipe)
是一种具有两个端点的通信通道:有一端句柄的进程可以和有另一端句柄的进程通信。管道可以是单向-一端是只读的,另一端点是只写的;也可以是双向的一管道的两端点既可读也可写。
匿名管道(Anonymous Pipe)是在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。
4. Sockets
5.WM_COPYDATA消息
2. 如何利用信号量机制实现多进程访问临界资源
进程互斥 定义:两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥.
在多道程序环境下,存在着临界资源,它是指多进程存在时必须互斥访问的资源。也就是某一时刻不允许多个进程同时访问,只能单个进程的访问。我们把这些程序的片段称作临界区或临界段,它存在的目的是有效的防止竞争条件又能保证最大化使用共享数据。而这些并发进程必须有好的解决方案,才能防止出现以下情况:多个进程同时处于临界区,临界区外的进程阻塞其他的进程,有些进程在临界区外无休止的等待。除此以外,这些方案还不能对CPU的速度和数目做出任何的假设。只有满足了这些条件,才是一个好的解决方案。
访问临界资源的循环进程可以这样来描述:
Repeat
entry section
Critical sections;
exit section
Remainder sectioni;
Until false
为实现进程互斥,可以利用软件的方法,也可以在系统中设置专门的同步机制来协调多个进程,但是所有的同步机制应该遵循四大准则:
1.空闲让进 当临界资源处于空闲状态,允许一个请求进入临界区的进程立即进入临界区,从 而有效的利用资源。
2.忙则等待 已经有进程进入临界区时,意味着相应的临界资源正在被访问,所以其他准备进 入临界区的进程必须等待,来保证多进程互斥。
3.有限等待 对要求访问临界资源的进程,应该保证该进程能在有效的时间内进入临界区,防 止死等状态。
4.让权等待 当进程不能进入临界区,应该立即释放处理机,防止进程忙等待。
早期解决进程互斥问题有软件的方法和硬件的方法,如:严格轮换法,Peterson的解决方案,TSL指令,Swap指令都可以实现进程的互斥,不过它们都有一定的缺陷,这里就不一一详细说明,而后来Kijkstra提出的信号量机制则更好的解决了互斥问题。
3. 关于3个进程共享一个临界资源
在操作系统理论中有一个非常重要的概念叫做P,V原语。在我们研究进程间的互斥的时候经常会引入这个概念,将P,V操作方法与加锁的方法相比较,来解决进程间的互斥问题。实际上,他的应用范围很广,他不但可以解决进程管理当中的互斥问题,而且我们还可以利用此方法解决进程同步与进程通信的问题。
[一]P,V原语理论
阐述P,V原语的理论不得不提到的一个人便是赫赫有名的荷兰科学家E.W.Dijkstra。如果你对这位科学家没有什么印象的话,提起解决图论中最短路径问题的Dijkstra算法应当是我们再熟悉不过的了。P,V原语的概念以及P,V操作当中需要使用到的信号量的概念都是由他在1965年提出的。
信号量是最早出现的用来解决进程同步与互斥问题的机制,包括一个称为信号量的变量及对它进行的两个原语操作。信号量为一个整数,我们设这个信号量为:sem。很显然,我们规定在sem大于等于零的时候代表可供并发进程使用的资源实体数,sem小于零的时候,表示正在等待使用临界区的进程的个数。根据这个原则,在给信号量附初值的时候,我们显然就要设初值大于零。
p操作和v操作是不可中断的程序段,称为原语。P,V原语中P是荷兰语的Passeren,相当于英文的pass, V是荷兰语的Verhoog,相当于英文中的incremnet。
P原语操作的动作是:
(1) sem减1;
(2) 若sem减1后仍大于或等于零,则进程继续执行;
(3) 若sem减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
V原语操作的动作是:
(1) sem加1;
(2) 若相加结果大于零,则进程继续执行;
(3) 若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。
需要提醒大家一点就是P,V操作对于每一个进程来说,都只能进行一次。而且必须成对使用。且在P,V愿语执行期间不允许有中断的发生。
对于具体的实现,方法非常多,可以用硬件实现,也可以用软件实现。我们采用如下的定义:
procere p(var s:samephore);
{
s.value=s.value-1;
if (s.value<0) asleep(s.queue);
}
procere v(var s:samephore);
{
s.value=s.value+1;
if (s.value<=0) wakeup(s.queue);
}
其中用到两个标准过程:
asleep(s.queue);执行此操作的进程控制块进入s.queue尾部,进程变成等待状态
wakeup(s.queue);将s.queue头进程唤醒插入就绪队列
对于这个过程,s.value初值为1时,用来实现进程的互斥。
虽软说信号量机制毕加锁方法要好得多,但是也不是说它没有任何的缺陷。由此我们也可以清晰地看到,这种信号量机制必须有公共内存,不能用于分布式操作系统,这是它最大的弱点。
[二]P,V原语的应用
正如我们在文中最开始的时候提到的,P,V原语不但可以解决进程管理当中的互斥问题,而且我们还可以利用此方法解决进程同步与进程通信的问题。
(1)用P V原语实现进程互斥
把临界区置于P(sem) 和V(sem)之间。当一个进程想要进入临界区时,它必须先执行P原语操作以将信号量sem减1,在进程完成对临界区的操作后,它必须执行V原语操作以释放它所占用的临界区。从而就实现了进程的互斥:
具体的过程我们可以简单的描述如下:
PA:
P(sem)
<S>;
V(sem)
PB:
P(sem)
<S>;
V(sem)
(2) 用P V原语实现进程同步
进程同步问题的解决同样可以采用这种操作来解决,我们假设两个进程需要同步进行,一个进程是计算进程,另一个进程是打印进程,那么这个时候两个进程的定义可以表示为:
PC(表示计算进程)
A: local buf
repeat
buf=buf
until buf=空
计算
得到计算结果
buf=计算结果
goto A
PP:(表示打印进程)
B: local pri
repeat
pri=buf
until pri!=空
打印buf中的数据
清除buf中的数据
goto B
相应用P,V原语的实现过程为:
PA: deposit(data)
Begin local x
P(bufempty)
按FIFO方式选择一个空缓冲区buf(x)
buf(x)=data
buf(x)置满标记
V(buffull)
end
PB:remove(data)
Begin local x
P(buffull)
按FIFO方式选择一个装满
数据的缓冲区buf(x)
data=buf(x)
buf(x)置空标记
V(bufempty)
end
(3)用P V原语实现进程通信
我们以邮箱通信为例说明问题:
邮箱通信满足的条件是:
<1>;发送进程发送消息的时候,邮箱中至少要有一个空格能存放该消息。
<2>;接收进程接收消息时,邮箱中至少要有一个消息存在。
发送进程和接收进程我们可以进行如下的描述:
Deposit(m)为发送进程,接收进程是remove(m). Fromnum为发送进程的私用信号量,信箱空格数n。mesnum为接收进程的私用信号量,初值为0.
Deposit(m):
Begin local x
P(fromnum)
选择空格x
将消息m放入空格x中
置格x的标志为满
V(mesnum)
end
Remove(m)
Begin local x
P(mesnum)
选择满格x
把满格x中的消息取出放m中
置格x标志为空
V(fromnum)
end
笔者仅从最基本的进程问题上论述P,V原语的应用。当然关于这一部分的应用是十分广泛的。比如操作系统文化史上非常经典的哲学家就餐问题,生产-消费问题,读者-写者问题,理发师问题等等。大家不妨尝试一下用信号量的方法进行实现。
4. 东秦的操作系统答案第二章
第二章
1. 什么是前趋图?为什么要引入前趋图?
答:前趋图(Precedence Graph)是一个有向无循环图,记为DAG(Directed Acyclic
Graph),用于描述进程之间执行的前后关系。
2. 画出下面四条语句的前趋图:
S1=a:=x+y; S2=b:=z+1; S3=c:=a – b; S4=w:=c+1;
答:其前趋图为:
3. 什么程序并发执行会产生间断性特征?
答:程序在并发执行时,由于它们共享系统资源,为完成同一项任务需要相互合作,致使这
些并发执行的进程之间,形成了相互制约关系,从而使得进程在执行期间出现间断性。
4.程序并发执行时为什么会失去封闭性和可再现性?
答:程序并发执行时,多个程序共享系统中的各种资源,因而这些资源的状态由多个程序改变,致使程序运行失去了封闭性,也会导致其失去可再现性。
5.在操作系统中为什么要引入进程概念?它会产生什么样的影响?
答:为了使程序在多道程序环境下能并发执行,并对并发执行的程序加以控制和描述,在操作系统中引入了进程概念。
影响: 使程序的并发执行得以实行。
6.试从动态性,并发性和独立性上比较进程和程序?
答:(1)动态性是进程最基本的特性,表现为由创建而产生,由调度而执行,因得不到资源
而暂停执行,由撤销而消亡。进程有一定的生命期,而程序只是一组有序的指令集合,是静
态实体。
(2)并发性是进程的重要特征,同时也是OS 的重要特征。引入进程的目的正是为了使
其程序能和其它进程的程序并发执行,而程序是不能并发执行的。
(3)独立性是指进程实体是一个能独立运行的基本单位,也是系统中独立获得资源和独
立调度的基本单位。对于未建立任何进程的程序,不能作为独立单位参加运行。
7.试说明PCB 的作用,为什么说PCB 是进程存在的惟一标志?
答:PCB 是进程实体的一部分,是操作系统中最重要的记录型数据结构。作用是使一个在
多道程序环境下不能独立运行的程序,成为一个能独立运行的基本单位,成为能与其它进程
并发执行的进程。OS是根据PCB对并发执行的进程进行控制和管理的。
8.试说明进程在三个基本状态之间转换的典型原因。
答: (1)就绪状态→执行状态:进程分配到CPU资源
(2)执行状态→就绪状态:时间片用完
(3)执行状态→阻塞状态:I/O请求
(4)阻塞状态→就绪状态:I/O完成
9.为什么要引入挂起状态?该状态有哪些性质?
答:引入挂起状态处于五种不同的需要: 终端用户需要,父进程需要,操作系统需要,对换
北京石油化工学院信息工程学院计算机系5/48
《计算机操作系统》习题参考答案余有明与计07和计G09的同学们编着 5/48
需要和负荷调节需要。处于挂起状态的进程不能接收处理机调度。
10.在进行进程切换时,所要保存的处理机状态信息有哪些?
答:进行进程切换时,所要保存的处理机状态信息有:
(1)进程当前暂存信息
(2)下一指令地址信息
(3)进程状态信息
(4)过程和系统调用参数及调用地址信息。
11.试说明引起进程创建的主要事件。
答:引起进程创建的主要事件有:用户登录、作业调度、提供服务、应用请求。
12.试说明引起进程被撤销的主要事件。
答:引起进程被撤销的主要事件有:正常结束、异常结束(越界错误、保护错、非法指令、
特权指令错、运行超时、等待超时、算术运算错、I/O 故障)、外界干预(操作员或操作系
统干预、父进程请求、父进程终止)。
13.在创建一个进程时所要完成的主要工作是什么?
答:
(1)OS 发现请求创建新进程事件后,调用进程创建原语Creat();
(2)申请空白PCB;
(3)为新进程分配资源;
(4)初始化进程控制块;
(5)将新进程插入就绪队列.
14.在撤销一个进程时所要完成的主要工作是什么?
答:
(1)根据被终止进程标识符,从PCB 集中检索出进程PCB,读出该进程状态。
(2)若被终止进程处于执行状态,立即终止该进程的执行,置调度标志真,指示该进程被
终止后重新调度。
(3)若该进程还有子进程,应将所有子孙进程终止,以防它们成为不可控进程。
(4)将被终止进程拥有的全部资源,归还给父进程,或归还给系统。
(5)将被终止进程PCB 从所在队列或列表中移出,等待其它程序搜集信息。
15.试说明引起进程阻塞或被唤醒的主要事件是什么?
答:a. 请求系统服务;b. 启动某种操作;c. 新数据尚未到达;d. 无新工作可做.
16.进程在运行时存在哪两种形式的制约?并举例说明之。
答:
(1)间接相互制约关系。举例:有两进程A 和B,如果A 提出打印请求,系统已把唯一的
一台打印机分配给了进程B,则进程A 只能阻塞;一旦B 释放打印机,A 才由阻塞改为就
绪。
(2)直接相互制约关系。举例:有输入进程A 通过单缓冲向进程B 提供数据。当缓冲空时,
计算进程因不能获得所需数据而阻塞,当进程A 把数据输入缓冲区后,便唤醒进程B;反
之,当缓冲区已满时,进程A 因没有缓冲区放数据而阻塞,进程B 将缓冲区数据取走后便
唤醒A。
17.为什么进程在进入临界区之前应先执行“进入区”代码?而在退出前又要执行“退出
区”代码?
答:为了实现多个进程对临界资源的互斥访问,必须在临界区前面增加一段用于检查欲访问
的临界资源是否正被访问的代码,如果未被访问,该进程便可进入临界区对资源进行访问,
并设置正被访问标志,如果正被访问,则本进程不能进入临界区,实现这一功能的代码为"
北京石油化工学院信息工程学院计算机系6/48
《计算机操作系统》习题参考答案余有明与计07和计G09的同学们编着 6/48
进入区"代码;
在退出临界区后,必须执行"退出区"代码,用于恢复未被访问标志,使其它进程能再访问此
临界资源。
18. 同步机构应遵循哪些基本准则?为什么?
答:同步机构应遵循的基本准则是:空闲让进、忙则等待、有限等待、让权等待
原因:为实现进程互斥进入自己的临界区。
19. 试从物理概念上说明记录型信号量wait 和signal。
答:wait(S):当S.value>0 时,表示目前系统中这类资源还有可用的。执行一次wait 操
作,意味着进程请求一个单位的该类资源,使系统中可供分配的该类资源减少一个,因此描
述为S.value:=S.value-1;当S.value<0时,表示该类资源已分配完毕,进程应调用block
原语自我阻塞,放弃处理机,并插入到信号量链表S.L中。
signal(S):执行一次signal操作,意味着释放一个单位的可用资源,使系统中可供分配
的该类资源数增加一个,故执行S.value:=S.value+1 操作。若加1 后S.value≤0,则表
示在该信号量链表中,仍有等待该资源的进程被阻塞,因此应调用wakeup 原语,将S.L
链表中的第一个等待进程唤醒。
20.你认为整型信号量机制是否完全遵循了同步机构的四条准则?
答:整型信号量机制不完全遵循同步机制的四条准则,它不满足“让权等待”准则。
21.如何利用信号量机制来实现多个进程对临界资源的互斥访问?并举例说明之。
答:为使多个进程互斥访问某临界资源,只需为该资源设置一互斥信号量mutex,并设其
初值为1,然后将各进程访问该资源的临界区CS置于wait(mutex)和signal(mutex)操作
之间即可。这样,每个欲访问该临界资源的进程在进入临界区之前,都要先对mutex 执行
wait 操作,若该资源此刻未被访问,本次wait 操作必然成功,进程便可进入自己的临界区,
这时若再有其他进程也欲进入自己的临界区,此时由于对mutex 执行wait操作定会失败,
因而该进程阻塞,从而保证了该临界资源能被互斥访问。当访问临界资源的进程退出临界区
后,应对mutex执行signal 操作,释放该临界资源。利用信号量实现进程互斥的进程描述
如下:
Var mutex: semaphore:=1;
begin
parbegin
process 1: begin
repeat
wait(mutex);
critical section
signal(mutex);
remainder seetion
until false;
end
process 2: begin
repeat
wait(mutex);
critical section
signal(mutex);
remainder section
until false;
end
parend
22.试写出相应的程序来描述图2-17所示的前驱图。
答:(a)Var a, b, c, d, e, f, g, h; semaphore:= 0, 0, 0, 0, 0, 0, 0, 0;
begin
parbegin
begin S1; signal(a); signal(b); end;
begin wait(a); S2; signal(c); signal(d); end;
begin wait(b); S3; signal(e); end;
begin wait(c); S4; signal(f); end;
begin wait(d); S5; signal(g); end;
begin wait(e); S6; signal(h); end;
begin wait(f); wait(g); wait(h); S7; end;
parend
end
(b)Var a, b, c, d, e, f, g, h,i,j; semaphore:= 0, 0, 0, 0, 0, 0, 0,0,0, 0;
begin
parbegin
begin S1; signal(a); signal(b); end;
begin wait(a); S2; signal(c); signal(d); end;
begin wait(b); S3; signal(e); signal(f); end;
begin wait(c); S4; signal(g); end;
begin wait(d); S5; signal(h); end;
begin wait(e); S6; signal(i); end;
begin wait(f); S7; signal(j); end;
begin wait(g);wait(h); wait(i); wait(j); S8; end;
parend
end
23.在生产者消费者问题中,如果缺少了signal(full)或signal(empty),对执行结果有何影响?
答:
如果缺少signal(full),那么表明从第一个生产者进程开始就没有改变信号量full 值,
即使缓冲池产品已满,但full 值还是0,这样消费者进程执行wait(full)时认为缓冲池是空
而取不到产品,消费者进程一直处于等待状态。
如果缺少signal(empty),在生产者进程向n个缓冲区投满产品后消费者进程才开始从
中取产品,这时empty=0,full=n,那么每当消费者进程取走一个产品empty 值并不改变,
直到缓冲池取空了,empty 值也是0,即使目前缓冲池有n 个空缓冲区,生产者进程要想
再往缓冲池中投放产品也会因为申请不到空缓冲区被阻塞。
24.在生产消费者问题中,如果将两个wait 操作即wait(full)和wait(mutex)互换位置,
或者将signal(mutex)与signal(full)互换位置,结果如何?
答:将wait(full)和wait(mutex)互换位置后,可能引起死锁。考虑系统中缓冲区全满时,
若一生产者进程先执行了wait(mutex)操作并获得成功,则当再执行wait(empty)操作时,
它将因失败而进入阻塞状态,它期待消费者进程执行signal(empty)来唤醒自己,在此之前,
它不可能执行signal(mutex)操作,从而使试图通过执行wait(mutex)操作而进入自己的临
界区的其他生产者和所有消费者进程全部进入阻塞状态,这样容易引起系统死锁。
若signal(mutex)和signal(full)互换位置后只是影响进程对临界资源的释放次序,而
不会引起系统死锁,因此可以互换位置。
25.我们在为某一临界资源设置一把锁W,当W=1时表示关锁,当W=0时表示锁已打开。
试写出开锁和关锁的原语,并利用他们实现互斥。
答:整型信号量:lock(W): while W=1 do no-op
W:=1;
unlock(W): W:=0;
记录型信号量:lock(W): W:=W+1;
if(W>1) then block(W, L)
unlock(W): W:=W-1;
if(W>0) then wakeup(W, L)
例子:
Var W:semaphore:=0;
begin
repeat
lock(W);
critical section
unlock(W);
remainder section
until false;
end
26.试修改下面生产者-消费者问题解法中的错误:
答: procer:
begin
repeat
…
procer an item in nextp;
wait(mutex);
wait(full); /* 应为wait(empty),而且还应该在wait(mutex)的前面 */
buffer(in):=nextp;
/* 缓冲池数组游标应前移: in:=(in+1) mod n; */
signal(mutex);
/* signal(full); */
until false;
end
consumer:
begin
repeat
wait(mutex);
wait(empty); /* 应为wait(full),而且还应该在wait(mutex)的前面 */
nextc:=buffer(out);
out:=out+1; /* 考虑循环,应改为: out:=(out+1) mod n; */
signal(mutex);/* signal(empty); */
consumer item in nextc;
until false;
end
27.试利用记录型信号量写出一个不会出现死锁的哲学家进餐问题的算法.
答:Var chopstick:array[0,…,4] of semaphore;
所有信号量均被初始化为1,第i 位哲学家的活动可描述为:
Repeat
Wait(chopstick[i]);
Wait(. chopstick[(i+1) mod 5]);
…
Ea.t ;
…
Signal(chopstick[i]);
Signal(chopstick[(i+1) mod 5])
Ea.t ;
…
Think;
Until false;
28.在测量控制系统中的数据采集任务,把所采集的数据送一单缓冲区;计算任务从该单
缓冲中取出数据进行计算.试写出利用信号量机制实现两者共享单缓冲的同步算法。
答:
a. Var mutex, empty, full: semaphore:=1, 1, 0;
gather:
begin
repeat
……
gather data in nextp;
wait(empty);
wait(mutex);
buffer:=nextp;
signal(mutex);
signal(full);
until false;
end
compute:
begin
repeat
……
wait(full);
wait(mutex);
nextc:=buffer;
signal(mutex);
signal(empty);
compute data in nextc;
until false;
end
b. Var empty, full: semaphore:=1, 0;
gather:
begin
repeat
……
gather data in nextp;
wait(empty);
buffer:=nextp;
signal(full);
until false;
end
compute:
begin
repeat
……
wait(full);
nextc:=buffer;
signal(empty);
compute data in nextc;
until false;
end
29.画图说明管程由哪几部分组成,为什么要引入条件变量?
答:管程由四部分组成:①管程的名称;②局部于管程内部的共享数据结构说明;③对该数
据结构进行操作的一组过程;④对局部于管程内部的共享数据设置初始值的语句;
当一个进程调用了管程,在管程中时被阻塞或挂起,直到阻塞或挂起的原因解除,而在此期
间,如果该进程不释放管程,则其它进程无法进入管程,被迫长时间地等待。为了解决这个
问题,引入了条件变量condition。
30.如何利用管程来解决生产者与消费者问题?
答:首先建立一个管程,命名为ProclucerConsumer,包括两个过程:
(1)Put(item)过程。生产者利用该过程将自己生产的产品放到缓冲池,用整型变
量count 表示在缓冲池中已有的产品数目,当count≥n 时,表示缓冲池已满,生产者须
等待。
(2)get(item)过程。消费者利用该过程从缓冲池中取出一个产品,当count≤0
时,表示缓冲池中已无可取的产品,消费者应等待。
PC 管程可描述如下:
type procer-consumer =monitor
Var in,out,count:integer;
buffer:array[0,…,n-1]of item;
notfull,notempty:condition;
procere entry dot(item)
begin
if count>=n then not full.wait;
buffer(in):=nextp;
in:=(in+1)mod n;
count:=count+1;
if notempty.queue then notempty.signal;
end
procere entry get(item)
begin
if count<=0 then not full.wait;
nextc:=buffer(out);
out:=(out+1)mod n;
count:=count-1;
if notfull.quene then notfull.signal;
end
begin in:=out:=0;
count:=0
end
在利用管程解决生产者一消费者问题时,其中的生产者和消费者可描述为:
procer: begin
pepeat
proce an inem in nestp
PC.put(item);
until false;
end
consumer: begin
repeat
PC.get(item);
consume the item in enxtc;
until false;
end
31.什么是AND信号量?试利用AND信号量写出生产者一消费者问题的解法。
答:为解决并行带来的死锁问题,在wait 操作中引入AND 条件,其基本思想是将进
程在整个运行过程中所需要的所有临界资源,一次性地全部分配给进程,用完后一次性释放。
解决生产者-消费者问题可描述如下:
var mutex,empty,full: semaphore:=1,n,0;
buffer: array[0,...,n-1] of item;
in,out: integer:=0,0;
begin
parbegin
procer: begin
repeat
…
proce an item in nextp;
…
wait(empty);
wait(s1,s2,s3,...,sn); //s1,s2,...,sn为执行生产者进程除empty 外其余的条件
wait(mutex);
buffer(in):=nextp;
in:=(in+1) mod n;
signal(mutex);
signal(full);
signal(s1,s2,s3,...,sn);
until false;
end
consumer: begin
repeat
wait(full);
wait(k1,k2,k3,...,kn); //k1,k2,...,kn 为执行消费者进程除full 外其余的条件
wait(mutex);
nextc:=buffer(out);
out:=(out+1) mod n;
signal(mutex);
signal(empty);
signal(k1,k2,k3,...,kn);
consume the item in nextc;
until false;
end
parend
end
32.什么是信号量集?试利用信号量集写出读者一写者问题的解法。
答:对AND信号量加以扩充,形成的信号量集合的读写机制。
解法:Var RN integer;
L,mx: semaphore:=RN,1;
begin
parbegin
reader:begin
repeat
Swait(L,1,1);
Swait(mx,1,1);
…
perform read operation;
…
Ssignal(L,1);
until false
end
writer:begin
repeat
Swait(mx,1,1;L,RN,0);
perform write operation;
Ssignal(mx,1);
until false
end
parend
end
33.试比较进程间的低级与高级通信工具。
答:用户用低级通信工具实现进程通信很不方便,效率低,通信对用户不透明,所有操作都
必须由程序员来实现,而高级通信工具弥补了这些缺陷,用户直接利用操作系统提供的一组
通信命令,高效地传送大量的数据。
34.当前有哪几种高级通信机制?
答:共享存储器系统、消息传递系统以及管道通信系统。
35.消息队列通信机制有哪几方面的功能?
答:(1)构成消息(2)发送消息(3)接收梢息(4)互斥与同步。
36.为什么要在OS 中引入线程?
答:在操作系统中引入线程,则是为了减少程序在并发执行时所付出的时空开销,使OS具
有更好的并发性,提高CPU的利用率。进程是分配资源的基本单位,而线程则是系统调度的
基本单位。
37.试说明线程具有哪些属性?
答:(1)轻型实体(2)独立调度和分派的基本单位(3)可并发执行(4)共享进程资源。
38. 试从调度性,并发性,拥有资源及系统开销方面对进程和线程进行比较。
答:
(1)调度性。线程在OS 中作为调度和分派的基本单位,进程只作为资源拥有的基本单位。
(2)并发性。进程可以并发执行,一个进程的多个线程也可并发执行。
(3)拥有资源。进程始终是拥有资源的基本单位,线程只拥有运行时必不可少的资源,本
身基本不拥有系统资源,但可以访问隶属进程的资源。
(4)系统开销。操作系统在创建、撤消和切换进程时付出的开销显着大于线程。
39. 为了在多线程OS 中实现进程之间的同步与通信,通常提供了哪几种同步机制?
答:同步功能可以控制程序流并访问共享数据,从而并发执行多个线程。共有四种同步模型:
互斥锁、读写锁、条件变量和信号。
40.用于实现线程同步的私用信号量和公用信号量之间有何差别?
答:
(1)私用信号量。当某线程需利用信号量实现同一进程中各线程之间的同步时,可调用创
建信号量的命令来创建一个私用信号量,其数据结构存放在应用程序的地址空间中。
(2)公用信号量。公用信号量是为实现不同进程间或不同进程中各线程之间的同步而设置
的。其数据结构是存放在受保护的系统存储区中,由OS为它分配空间并进行管理。
41.何谓用户级线程和内核支持线程?
答:
(1)用户级线程:仅存在于用户空间中的线程,无须内核支持。这种线程的创建、撤销、
线程间的同步与通信等功能,都无需利用系统调用实现。用户级线程的切换通常发生在一个
应用进程的诸多线程之间,同样无需内核支持。
(2)内核支持线程:在内核支持下运行的线程。无论是用户进程中的线程,还是系统线程
中的线 程,其创建、撤销和切换等都是依靠内核,在内核空间中实现的。在内核空间里还
为每个内核支持线程设置了线程控制块,内核根据该控制块感知某线程的存在并实施控制。
42.试说明用户级线程的实现方法。
答:用户级线程是在用户空间中的实现的,运行在“运行时系统”与“内核控制线程”的中
间系统上。运行时系统用于管理和控制线程的函数的集合。内核控制线程或轻型进程LWP
可通过系统调用获得内核提供服务,利用LWP进程作为中间系统。
43.试说明内核支持线程的实现方法。
答:系统在创建新进程时,分配一个任务数据区PTDA,其中包括若干个线程控制块TCB
空间。创建一个线程分配一个TCB,有关信息写入TCB,为之分配必要的资源。当PTDA
中的TCB 用完,而进程又有新线程时,只要所创建的线程数目未超过系统允许值,系统可
在为之分配新的TCB;在撤销一个线程时,也应回收线程的所有资源和TCB。