现在的使用情景是多资源多数量, 就是一个进程需要申请多个资源,每个资源数量又要求多个。描述资源的结构体做出了改动:
typedef struct{
int value;
int d;
int t;
struct process_control_block * list;
} semaphore;
原有的value和list阻塞队列保留,新增属性t和d。d表示进程需要的某类资源的数量,t表示进程能执行需要某类资源数量的最小值,value表示当前某类资源个数。
这里的dt必须满足关系t>=d才能保证进程可以执行。解释一下:假设d=5,也就是进程本身需要5个A资源;t=7,也就是进程最小需要7个A类资源才能执行,多出来的两个是分给操作系统使用的,因为控制进程执行的指令也需要操作系统分配资源。当然当前i资源数S也必须大于7才能保证进程整体可以执行。
信号量集的PV操作:
wait(S1, t1, d1; …; Sn, tn, dn)
if S1>= t1 and … and Sn>=tn then
for i:=1 to n do
Si:= Si - di ;
endfor
else
Place the executing process in the waiting queue of the first Si with Si < ti
and set its program counter to the beginning of the Swait Operation
endif
signal(S1, d1, …, Sn, dn)
for i:=1 to n do
Si:= Si +di ;
Remove all the process waiting in the queue associated with Si into the ready
queue
endfor
wait的参数是一个个的std,分别代表一种资源。和AND型信号量是类似的,每类资源都达到要求才能继续执行,否则进程被放入资源Si的阻塞队列。signal也是将阻塞队列中的进程拿出。和AND型信号量的工作机制很相似。
信号量集是由整形信号量一步步演变而来,每次演变都继承了上次的工作机制并且进行了缺点的改造。信号量集的已经可以适用较多的情景了。如果wait(S,1,1)那么就是需要1种资源,需要的资源数量为1,如果S>=1这就退化成了记录型信号量;如果S=1就退化成了互斥信号量(整型信号量)。
wait(S,1,0)相当于可控开关,当S>=1时,允许多个进程进入某临界区。S=0时,任何进程都无法进入临界区。