在某些情况下, 需要在关键部分中同时执行多个线程。但是, 当我们需要在关键部分中同时具有多个线程时, 可以使用计数信号量。
【计数信号量】信号量实现的编程代码如下所示, 其中包括信号量的结构以及可以在关键部分执行进入和退出操作的逻辑。
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){ S.value = http://www.srcmini.com/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();
} elsereturn;
}up (Semaphore s){ S.value = http://www.srcmini.com/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, 然后检查它是负数还是零。如果为负, 则意味着至少一个进程正在阻塞状态下等待, 因此, 为了确保有限的等待, 被阻塞进程列表中的第一个进程将被唤醒并进入临界区。
阻止列表中的进程将按照其休眠的顺序被唤醒。如果计数信号量的值为负, 则表明处于阻塞状态的进程数;如果为正, 则表明关键部分中可用的插槽数。
推荐阅读
- 系统CPU调度
- 磁盘的连续分配
- 内存压缩
- 动态分区的位图
- 二进制信号量或互斥量
- 贝拉迪异常(Belady’s Anomaly)
- 系统二进制地址基础
- 什么是文件(文件的属性)
- 操作系统进程的属性