信号量:二进位信号量和计数信号量
2020-04-28 本文已影响0人
雨幻逐光
什么是信号量(semaphore)
信号量(semaphore)是一个被线程共享的非负变量。信号量是一个发信号的机制。一个等待一个信号量的线程可以被其他线程通知(signal)。这个机制通过 wait 和 signal 两个原子操作(atomic operations)来实现进程同步。
一个信号量要么允许访问资源,要么不允许访问资源。二者只能选其一。而具体是哪一种,则要看设置。
信号量的特点
下面是信号量的一些特点:
- 它是一个机制。该机制支持多任务的同时进行
- 它是一个低层级的(low-level)的同步机制
- 信号量的存储值一直是非负的
- 信号量可以使用测试操作和中断来实现。这些操作和中断需要用文件描述符来执行
信号量的类型
最常见的两种信号量:
- 计数信号量(Counting semaphores)
- 二进位信号量(Binary semaphores)
计数信号量
这种信号量用一个计数来帮助任务被获取(be acquired)或释放(be released)数次。
- 如果起始时,计数器的计数值为0(count = 0),那么创建出来的信号量就应该在不可获得的状态(unavailable state)。
- 如果起始时,计数器的计数值大于0(count > 0),那么创建出来的信号量就应该在可获得的状态(available state)。而且,总共的获取次数(tokens)就等于计数器的值。
具体机制如下图所示:
计数信号量二进位信号量
二进位信号量和计数信号量非常相似,但是他们的计数值只能限制在0和1两个数字。在这种信号量下,等待(wait)操作只能在信号量等于1(semaphore = 1)时工作。而通知(signal)操作只有在信号量等于0(semaphore = 0)时才能成功。二进位信号量的实现要比计数信号量的实现要简单。
二进位信号量
信号量的等待操作和通知操作
信号量的等待操作(wait operation)和通知操作(signal operation)是用来实现同步的。信号量操作的不得是为了互相独立。
等待操作(wait operation)
等待操作(wait operation)用来帮助我们控制任务是否可以进入关键的部分。当信号量是正的时候,信号量将被减一。如果当信号量为负数或者零的时候,等待操作不执行任何操作。
当信号量被递减后,信号量值为负数或者零时,该指令将被挂起保持,直到信号量重新满足大于0的条件。
function wait(S){
while ( S < 0);
S--;
}
通知操作(signal operation)
通知操作(signal operation)是用于控制一个任务退出某个重要部分。当信号量的值是负的时候,信号量将被加一。
function signal(S){
while (S >= 0);
S++;
}
计数信号量vs二进位信号量
下面列举了计数信号量和二进位信号量的主要不同:
计数信号量 | 二进位信号量 |
---|---|
没有互斥 | 互斥 |
任意整数值 | 只有0和1 |
多于一个槽(slot) | 只有一个槽(slot) |
Provide a set of Processes | It has a mutual exclusion mechanism |