本站动态:
第三章: 进程同步机制
作者:shosh 日期:2009-11-15
第三章: 进程同步机制
3.1 信号量和P、V操作
信号量:表示资源使用情况的一种数据结构
struct{
int n; //正数表示当前可用的资源个数,负数表示等待该种资源的进程个数
PCB* pcbList; //等待该种资源的进程(PCB)列表
}
信号量的值仅由P、V操作来改变
原语:机器指令的延生,往往是为完成某些特定功能而编制的一段系统程序,其操作具有不可分割性(一次性完成)
P操作P(S):也叫wait操作,S为相应的信号量
S = S - 1;
if (S < 0)
{
//资源不足,得不到分配的情况
将本进程链入 S 的队尾;
阻塞本进程;
}
else
{
本进程继续执行;
}
V操作V(S): 也叫signal操作
S = S + 1;
if (S > 0)
{
//说明目前没有进场在等待该资源
本进程继续执行;
}
else
{
//说明有进程在等待该资源
释放S队列上的第一个PCB;
本进程继续执行;
}
3.2 同步机制的应用
使用PV操作实现进程互斥
- 在每个进程中,P(mutex)和V(mutex)必须成对出现,并且先P后V
- 互斥信号量mutex的初值一般为1
使用PV操作实现简单同步
例如 : 供者和用者共同使用缓冲区的问题
分析和解答:供者和用者两个需要合作来完成,它们之间的桥梁是缓冲区,它们之间的动作需要按照一定的先后顺序才能顺利进行,它们之间的关系是同步。临界资源是缓冲区,因为供者在向缓冲区写入数据的时候,用者不能从缓冲区读数据,同样,在缓冲区数据写满后,用者开始读缓冲区数据,这时供者不能往缓冲区里写数据,直到用者从缓冲区中取完数据。缓冲区有两个临界状态,一是空了,一是满了。使用两个信号量来表示,E表示空了的状态,F表示满了的状态,初始状态下缓冲区是空着的,所以E = 1, F = 0。对于供者,先用P操作获得空着的缓冲区,在写满数据之后,再用V操作释放一个满了的缓冲区的信号量;而用者则使用P操作获得写满的缓冲区,在取完数据之后,再用V操作释放清空的缓冲区的信号量。
所以供者的程序如下:
P(E);
写数据到缓冲区;
V(F);
用者的程序如下:
P(F);
将缓冲区中的数据全部取走;
V(E);
不难理解为什么P操作又叫wait操作,而V操作又叫signal操作。因为P操作会确保获得满足信号量要求的临界资源,如果暂时没有,会等待直到其他进程释放出该临界资源并得到后再继续执行;V操作会释放出一种临界资源,发出一个信号,如果有其他进程在等待该资源,会将该资源交给队列最前面的那个进程。
这里有个比较容易混淆的问题:既然临界资源只有缓冲区一种,为什么使用两个信号量E和F?回顾一下什么是信号量,信号量并不代表临界资源,而是临界资源的状态,既然临界资源有两种状态空着和满了,就可以用两个信号量来表示。另外初始值E = 1表示有一个空着的缓冲区,而不是表示缓冲区是空着的,F = 0 表示没有满了的缓冲区,而不是表示缓冲区没有满(或者是空着的)。
使用PV操作的说明:
- 确定彼此关系和信号量种类
- 设定信号量初值
- 同一信号量的PV操作要成对出现,只是互斥的PV操作在同一进程中成对出现,而同步的PV操作在不同进程中成对出现。
同步互斥的经典例子:生产者和消费者
生产者和消费者的问题和上面提到的供着和用者的例子类似,只是供着和用者只有一个缓冲区,而生产者和消费者有N个缓冲区,构成缓冲池。当N=1时候,本问题就成为了供者和用者的问题,可见,供者和用者的问题只是本问题的一个特例而已。
1、消费者只有在生产者生产出产品之后才能消费(缓冲池中有满的缓冲区时才可以让消费者从缓冲区取走产品消费)
2、生产者在缓冲池满了以后要暂停生产,直到有空的缓冲区出现
3、为避免混乱,生产者和消费者互斥使用缓冲池
上面的1、2点讲的就是供者和用者中提到的同步问题,第3点讲的是互斥问题。
同步问题同样设E和F两个信号量,E表示缓冲池中空缓冲区的数目,初始状态下E = 0; F表示缓冲池中满了的缓冲区的个数,初始状态下F = N。另外增加缓冲池的互斥信号量M, 初始状态下M = 1(表示只用一个缓冲池可供使用)
对于生产者,他要做的事情是:1、等待获得空缓冲区;2、等待获得缓冲池的使用权;3、往空缓冲区中放入产品;4、释放缓冲池使用权(通知缓冲池可以使用了);5、通知新增一个满的缓冲区(一个新产品)
对于消费者,他要做的事情是:1、等待获得满的缓冲区;2、等待获得缓冲池的使用权;3、从满的缓冲区中取走产品;4、释放缓冲池使用权(通知缓冲池可以使用了);5、通知新增一个空的缓冲区
生产者和消费者都要做5步动作,其中他们的第4步和第5步都是可以互换的,但是其他步骤是不能改变顺序的,尤其是第一步和第二步。如果第一步和第二步颠倒,很可能发生锁住的问题(死锁),导致生产者和消费者都不能往下进行。举个例子:假如消费者先获得了缓冲池的使用权,然后等待获得满的缓冲区,不过当时没有满的缓冲区,它就在一直占用缓冲池的情况下处于等待状态;而生产者因为得不到缓冲池的使用权,也无法让缓冲区变慢,这样消费者也就永远无法获得满的缓冲区(产品),于是生产者和消费者谁也干不了活了。不过有个原则是:互斥信号量的PV操作要成对出现在临界区的前后,所以第4步和第5步最好不要颠倒,既便于记忆,又避免出错。
上面的步骤中凡是使用了”等待获得“来描述的,都是P操作,要获得的东西是P操作的信号量;凡是用到了”释放“或”通知“的步骤都是V操作,释放或通知的东西就是V操作的信号量。
注意:
- P(mutex)和V(mutex)分别出现在临界区的前后
- 各信号量的P、V操作都要成对出现
- 两个P操作的顺序不能颠倒
上一篇
下一篇

文章来自:
Tags:
相关日志:






