避免出现多个资源共享导致的死锁,那么在每个进程把需要的各种资源都得到并完成计算之后释放,另一个进程也在拿到需要的全部资源之后计算,这样就不会出现交叉使用资源的情况。每个进程把需要的全部资源拿到后才会进入临界区。
那么wait操作就需要改变:
wait(S1, S2, …, Sn)
{
While(TRUE)
{
if (S1 >=1 and … and Sn>=1 ){
for( i=1 ;i<=n; i++) Si--;
break;
}
else{
Place the process in the waiting queue associated with the first Si
found with Si < 1,and set the progress count of this process to the
beginning of Swait operation
}
}
}
S1到Sn都表示所需资源,资源数都大于1,对每个资源进行--表示资源被占用,分配好资源之后跳出循环,wait操作结束。如果其中某个资源Si得不到满足,会执行else中的内容:把进程放进Si关联的阻塞队列中,然后程序计数器把指针移向wait操作开始。(wait操作是原语,遵循要执行都执行,执行不了就从头重新执行)
AND型信号量的signal操作:
signal(S1, S2, …, Sn){
while(TRUE){
for (i=1; i<=n; i++) {
Si++ ;
Remove all the process waiting in the queue associated with Si into
the ready queue
}
}
}
signal操作表示的是释放资源,把S1到Sn全部资源释放,并且把S1到Sn关联的阻塞队列全部置空,阻塞队列中的进程直接调度到就绪队列中。
AND型信号量满足了 “多种资源,数量为1”的使用情景,但是实际上还会有多种资源数量不固定的情景,AND型信号量显然处理不了这种情况的进程调度。为了解决多资源多数量的情况,出现了信号量集。