Semaphore - 信号量

1. 什么是信号量

一个信号量是一个整数变量,在多个进程间进行共享. 信号量的主要目的在于 :

  • 处理同步问题
  • 并发环境下用于共享资源的访问控制

信号量的取值取决于遇到的具体问题,通常,会使用可用资源的个数作为信号量的初始值。

2. 信号量操作

信号量包含两个独立的原子操作,也就是 waitsignal. 也被称之为 P (荷兰语Proberen(测试)的首字母) 和 V 荷兰语Verhogen(增加)的首字母.

假设 S 表示一个信号量,他的整数值代表了某种可用资源的数量,那么 waitsignal 操作分表可用如下的伪代码表示

wait

image-20201201204409486

如果 S 的值大于 0,wait 操作会简单的进行减 1 操作,表示仍有资源可以用于分配;如果 S 已经是 0 , 表示没有可用的资源进行分配, 那么调用 wait 操作的进程会进入休眠(sleep)状态

signal

image-20201201204646050

如果没有其它进程等待资源, signal 操作会进行一个加 1 操作;否则,一个等待的进程会被唤醒(操作系统调度器),最终,唤醒的进程获得了资源的访问控制权限。

简单总结

wait: (把信号量减1),若成功,则退出;若失败,则该进程被阻塞;

signal:(把信号量加1),如果发现有被阻塞的进程,则选择一个唤醒之。

3. 信号量的种类

  • Binary Semphore - 二元信号量

    二元信号量的取值只能是 0 或 1, 可以实现互斥的效果(mutex), 可以用来解决临界区(critial section)问题。

binary semphore is not a mutex ?

  • Counting Semphore - 计数信号量

    计数信号量的取值域是不受限制的,可以用来解决资源分配的同步问题。

信号量的实现,通常需要一个整数值来保存信号量的值,以及一个指针指向等待队列中下一个要执行的进程,同时要避免死锁(deadlock)和饥饿 (starvation)

死锁的情况

image-20201201214736878

进程 0 执行了 wait(S) 操作,然后进程被打断,进程 1 开始执行 wait(Q) 操作后,就开始等待信号量 S, 会被阻塞,然后进入休眠状态,当内核开始执行进程 0 时,信号量 Q 已经被使用,所以两个进程互相等待对方的情况,出现了死锁

如何解决 ?

4. 使用信号量的例子

临界区问题

临界区(critical section)是指代码的一部分,必须避免并发访问。 这时,可以使用一个二元信号量来解决这个问题,信号量的值初始化为 1. 保证互斥的执行临界区代码,一旦 signal 操作,内核会将休眠的进程添加到就绪队列,等待内核执行该进程时,就可以继续执行临界的代码。确保在任何时刻,临界区的代码只有一个和进程在执行

image-20201201215432904

以顺序执行

假设要执行代码片段 S1 和 S2 ,但是要求 S1 先执行, S2 后执行

image-20201201220621412

使用一个初始值为 0 的信号量就可以解决这个问题:

image-20201201220908667

生产者/消费者问题

在这个问题中,生产者往缓冲区中生产物品,消费中从缓冲区中拿出来消费,他们分别对应 Producer 进程和 Consumer 进程,这是,使用一个信号量 S 代表换取中的物品个数,初始化为 0.

image-20201201222814601

缓冲区满了,生产者应该停止生产,进入休眠状态,缓冲区空闲了,谁来通知 Producer 进程呢?

使用三个信号量:

empty: 表示缓冲区中剩余空间大小,初始化为缓冲区的大小

full:表示缓冲区中已用空间大小,初始化为 0

S 用来保护缓冲区同时只能被一个进程访问, 初始化 1

![image-20201201223208708](D:\Markdown 目录\Markdown 文档\工作\Java\img-assets\image-20201201223208708.png)·

生产者

如果 empty 信号量变为 0 ,生产者进入休眠状态;否则往缓冲区里进行生产,然后通知 full 信号量,因此会触发唤醒任何可能等待的消费者

消费者

如果 full 信号量变为 0 ,消费者进入休眠状态,否则从缓冲区中取出物品,并通知 empty 信号量,因此会触发唤醒任何需要进程生成的生成者

除非缓冲区中还有空间,否则生产者进入休眠状态;除非缓冲区中还有元素,否则消费者进入休眠状态

还有很多案例,包括哲学家吃饭问题,同一数据集上的读写问题….

工作中的例子

参考文献

[1] What is a Semaphore

[2] 哲学家进餐问题

[3] PV操作