信号量和P、V操作
*信号量:是一种特殊的数据结构。
功能:表示资源的实体。例如:设mutex是一个信号量,它有两部分,分别是:mutex.value (数值) mutex.L(指针)
特殊之处:
**每个信号量与一个队列关联
**其值只能通过初始化和P、V操作来访问
*信号量的类型
**公用信号量:用于进程间的互斥,初值通常为1
mutex.value=1;表示资源空闲,可供使用
=0;表示资源已被占用,无其他等待进程
=-n;表示资源已被占用,还有n个进程因等待资源而阻塞
**私有信号量:用于进程间的同步,初值通常为0或n
P、V操作(均是原语):
P操作:请求分配一个单位资源
P(S): //S为信号量
{
S=S-1;
if(S<0)
{
调用进程被阻塞
进入S的等待队列
}
}
V操作:释放一个单位资源
V(S): //S为信号量
{
S=S+1;
if(S<=0)
{
从S的等待队列中唤醒一个进程
使其进入就绪状态
}
}
信号量及P、V操作的应用
进程的互斥:
进程的同步:
利用信号量机制解决进程间的同步问题,这里以下图所示的计算进程c和打印进程P通过缓冲区Buffer传送数据的同步问题为例说明
C和P进程算法如下:
C:begin
repeat
Compute next nember;
add to Buffer;
until false
end
P:begin
repeat
take from Buffer;
print last number;
until false
end
C和P两进程并发执行,必须在执行序列上遵循以下规则,才能避免错误。
只有当C进程把数据送入Buffer后,P进程才能从Buffer中取出数据来打印,否则P进程只能等待。
只有当P进程从Buffer中取走数据后,C进程才能将新计算的数据再存入Buffer,否则C进程也只能等待。
为了实现进程同步,需采用同步信号量。为了满足第一条同步规则,设置一个同步信号量full,它代表的资源是缓冲器满,它的初值为0.这个资源是P进程所拥有,P进程可以申请该资源,对它施加P操作,如条件满足P进程可从Buffer中取数。而P进程的合作进程C对full信号量施加V操作,即它可释放该资源。当C进程将数据存入Buffer后,即可释放该资源供P进程再使用。
同样为了满足第二条同步规则,设置另一个同步信号量empty,它代表的资源是缓冲器空,它的初值为1.缓冲器空这个资源是进程C所拥有。它可以申请该资源,对它施加P操作。而它的合作进程P对empty信号量施加V操作。
实现C和P两进程同步的类PASCAL程序:
var: empty ,full:semaphore:=1,0;
begin
parbegin
c:begin
repeat
Compute next number;
P(empty);
add to buffer;
V(full);
until false
end
P:begin
repeat
P(full)
Take from Buffer
V(empty)
Print last number
until false
end
parend
end