记录型信号量
发布网友
发布时间:2022-11-28 02:46
我来回答
共1个回答
热心网友
时间:2023-10-20 09:52
记录型信号量:需要一个用于代表资源数目的整型变量value外,还应增加一个进程链表L,用于链接等待进程。两个数据项可描述为:
type semaphore=record
value:integer;
L:list of process;
end
图1
相应地,wait(S)和signal(S)操作可描述为:
procere wait(S)
var S:semaphore;
begin
S.value:=S.value-1;
if S.value<0 then block(S,L)
End
procere signal(S)
var S:semaphore;
begin
S.value:=S.value+1;
if S.value≤0 then wakeup(S,L);
end
在记录型信号量机制中,S.value的初值表示系统中某类资源的数目,因而又称为资源信号量,对它的每次wait操作,意味着进程请求一个单位的该资源,因此描述为S.value:=S.value-1;当S.value<0时,表示该类资源已分配完毕,因此进程应调用block原语,进行自我阻塞,放弃处理机,并插入到信号量链表S.L中。可见,该机制遵循了“让权等待”准则。此时S.value的绝对值表示在该信号量链表中已阻塞进程的数目。对信号量的每次signal操作,表示执行进程释放一个单位资源,故S.value:=S.value+1操作表示资源数目加1.若加1后仍是S.value≤0,则表示在该信号量链表中,仍有等待该资源的进程被阻塞,故还应该调用wakeup原语,将S.L链表中的第一个等待进程唤醒。如果S.value的初值为1,表示只允许一个进程访问临界资源,此时的信号量转化为互斥信号量。
以上内容摘之《计算机操作系统》,下面我谈谈对记录型信号量的认识:如上图1,你看上去是不是很像我们学习过的C语言定义的数据结构,它就是因此而得名的。只不过它是pascal语言书写的而已,那看下面两个方框,一个是wait,另一个是signal,是不是很像咱学的C语言啊。每次wait操作就是给进程分配一个单位的资源,每次signal操作就是进程释放一个单位资源。
现在我们假设我的电脑有两台打印机,所以S.value的初值为2,表示系统打印机的数目,称为资源信号量。进程A请求打印,那么系统对它执行一次wait操作,执行S.value:=S.value-1语句后S.value减1,S.value的值变为1,表示有一个资源空闲。执行if语句,S.value不小于0,结束。然后又来了一个进程B请求打印,系统对它又执行一次wait操作,执行S.value:=S.value-1语句后S.value减1,S.value的值变为0,表示没有空闲的资源。执行if语句,S.value不小于0,结束。又来一个进程C请求打印,系统对它又执行一次wait操作,执行S.value:=S.value-1语句后S.value减1,S.value的值变为-1,表示有一个进程没有得到打印机资源。执行if语句,S.value小于0,执行block(S,L),进行自我阻塞,放弃处理机,并插入到信号量链表S.L中。此时S.value的绝对值表示了在该信号量链表中已阻塞进程的数目。所以这个时候阻塞的进程为一个,即是进程C。
系统运行了一段时间后,A进程结束,在结束前执行了signal操作,当执行到S.value:=S.value+1语句时,S.value加1,即S.value变为0.然后执行 if 语句,S.value小于等于0,执行wakeup(S,L),从S.L链表中唤醒C进程。过了一会,B进程结束,同样执行signal操作,S.value变为1,表示有一个资源空闲。紧接着C进程也结束了,S.value变为2。S.value最终等于初值,等待其他的进程进行资源请求。