操作系统进程同步之——PV原语
一、操作系统的进程同步:
进程同步是指进程间一种直接的协同工作关系,是一些进程相互合作,共同完成一项任务。进程间的直接相互作用构成进程的同步。
二、进程的互斥
(1)进程互斥
某些资源一次只能为一个进程服务,因此各进程间互斥使用这些资源,进程间的这种关系就是进程的互斥。进程间的直接相互作用构成进程互斥。
(2)临界区
一次只能允许一个进程使用的资源叫做临界区资源或共享资源。进程中访问临界资源的那一段程序称为临界区。
三、同步机制
进程同步机制应满足的基本要求:
1)描述能力足够强 ,即解决各种进程间同步互斥问题
2)容易实现且效率高
3)使用方便
四、已有的同步机制
硬件同步机制;信号量及P、V操作;管程;条件临界域;路径表达式(用于集中式系统中);远程过程调用(适用于分布式系统中)等
五、PV原语
PV原语通过操作信号量来处理进程间的同步与互斥的问题。其核心就是一段不可分割不可中断的程序。
信号量的基本思路是用一种新的变量类型(semaphore)来记录当前可用资源的数量。有两种实现方式:1)semaphore的取值必须大于或等于0。0表示当前已没有空闲资源,而正数表示当前空闲资源的数量;2) semaphore的取值可正可负,负数的绝对值表示正在等待进入临界区的进程个数。
信号量是由操作系统来维护的,用户进程只能通过初始化和两个标准原语(P、V原语)来访问。初始化可指定一个非负整数,即空闲资源总数。
P原语:
P是荷兰语Proberen(测试)的首字母。为阻塞原语,负责把当前进程由运行状态转换为阻塞状态,直到另外一个进程唤醒它。操作为:申请一个空闲资源(把信号量减1),若成功,则退出;若失败,则该进程被阻塞;
V原语:
V是荷兰语Verhogen(增加)的首字母。为唤醒原语,负责把一个被阻塞的进程唤醒,它有一个参数表,存放着等待被唤醒的进程信息。操作为:释放一个被占用的资源(把信号量加1),如果发现有被阻塞的进程,则选择一个唤醒之。
六、举例说明
例1:某超市门口为顾客准备了100辆手推车,每位顾客在进去买东西时取一辆推车,在买完东西结完帐以后再把推车还回去。试用P、V操作正确实现顾客进程的同步互斥关系。
分析:把手推车视为某种资源,每个顾客为一个要互斥访问该资源的进程。因此这个例子为PV原语的第二种应用类型。
semaphore S_CartNum; // 空闲的手推车数量,初值为100
void consumer(void) // 顾客进程
{
P(S_CartNum);
买东西;
结帐;
V(S_CartNum);
}
例2:桌子上有一个水果盘,每一次可以往里面放入一个水果。爸爸专向盘子中放苹果,儿子专等吃盘子中的苹果。把爸爸、儿子看作二个进程,试用P、V操作使这两个进程能正确地并发执行。
分析:爸爸和儿子两个进程相互制约,爸爸进程执行完即往盘中放入苹果后,儿子进程才能执行即吃苹果。因此该问题为进程间的同步问题。
semaphore S_PlateNum; // 盘子容量,初值为1
semaphore S_AppleNum; // 苹果数量,初值为0
void father( ) // 父亲进程
{
while(1)
{
P(S_PlateNum);
往盘子中放入一个苹果;
V(S_AppleNum);
}
}
void son( ) // 儿子进程
{
while(1)
{
P(S_AppleNum);
从盘中取出苹果;
V(S_PlateNum);
吃苹果;
}
}