有一些情况需要同时在临界区执行多个进程。 但是,当我们需要同时在临界区中有多个进程时,可以使用计数信号量。
信号量实现的编程代码如下所示,其中包括信号量的结构以及在临界区中可以执行的入口和退出的逻辑。
struct Semaphore
{
int value; // processes that can enter in the critical section simultaneously.
queue type L; // L contains set of processes which get blocked
}
Down (Semaphore S)
{
SS.value = S.value - 1; //semaphore's value will get decreased when a new
//process enter in the critical section
if (S.value< 0)
{
put_process(PCB) in L; //if the value is negative then
//the process will get into the blocked state.
Sleep();
}
else
return;
}
up (Semaphore s)
{
SS.value = S.value+1; //semaphore value will get increased when
//it makes an exit from the critical section.
if(S.value<=0)
{
select a process from L; //if the value of semaphore is positive
//then wake one of the processes in the blocked queue.
wake-up();
}
}
}
在这种机制中,临界区的入口和退出是根据计数信号量的值执行的。在任何时间点计算信号量的值表示可以同时在临界区输入的最大进程数。
想要进入临界区的进程首先将信号量值减1,然后检查它是否为负值。如果它变为负数,则该过程被推入阻塞过程的列表(即q),否则它进入临界区。
当进程从临界区退出时,它会将计数信号量增加1,然后检查它是否为负值或零。如果它是负数,那么这意味着至少有一个进程在阻塞状态下等待,因此,为了确保有界等待,阻塞进程列表中的第一个进程将被唤醒并进入临界区。
被阻止列表中的进程将按其睡眠顺序进行唤醒。如果计数信号量的值为负数,则表示处于阻塞状态的进程数量,如果为正数,则表示临界区域中可用的插槽数量。