信号量机制
信号量机制是一种卓有成效的进程同步与互斥的工具。进程同步即是使在异步环境下的各进程按一定的顺序和速度执行;进程互斥即临界资源(公有资源)在某一时刻只允许被一个进程访问。
信号量机制主要包括信号量和PV操作。
信号量
信号量是一个整型变量,根据控制对量的不同赋予不同的值。
- 在实现进程互斥的场景中,信号量初值为1或资源的数量
- 在实现进程同步的场景中,信号量处置为0或某个正整数
信号量大于0时表示资源的可用数量,<0时表示阻塞队列中等待该资源的进程数量。
PV操作
- P操作:
S=S-1
若 S < 0,表示当前没有可用资源,进程进入等待队列 - V操作:
S=S+1
若 S <= 0, 表示阻塞队列中有等待该资源的进程,唤醒等待队列中的第一个进程。
使用PV操作实现进程的互斥控制
互斥控制是为了保护共享资源, 不让多个进程同时访问这个共享资源。一般最简单的互斥控制操作如下:
1 | P(信号量) |
信号量一般为1或者资源的数量,如当前资源数量为1,则信号量S初始值为1,当一个进程进来时执行P(S)
,将当前资源分配给当前进程,信号量对应减1,当前信号量S为0,这是其他进程调用P(S)
,S=S-1
当前信号量S为-1,则当前进程进入等待队列,直到获取资源的进程执行V(S)
释放资源,S=S+1
当前信号量S=0,唤醒之前等待队列中的第一个进程继续执行。
使用PV操作实现进程的同步控制
同步控制是为了处理进程间合作引起的互相制约的问题,一般讲信号量与消息联系起来。当信号量0时表示消息未产生;当信号量为非0时,表示消息已存在。进程通过P操作来判断消息是否已到达,通过V操作通知消息已准备好。实现同步控制的操作如下:
1 | 进程A 进程B |
当进程B产生消息后,由进程A进程读取。初始信号量为0,第一种情况:进程A执行P(S)
,此时信号量为-1,进程进去等待队列,当进程B执行V(S)
操作后产生一条消息,此时信号量为0,这时进程A被唤醒获取到对应的消息;第二种情况:进程B先执行V(S)
产生了一条消息,此时信号量为1,进程A执行P(S)
,获取到这条消息,此时信号量恢复到0;通过这种同步的控制使得进程执行的顺序得到了保证,不管什么情况下总是先进程B产生消息,进程A消费消息。
如果是一个持续运行的消息生产-消费的程序,这种控制会造成消息缓冲队列的溢出,这个时候需要引入另外一个信号量来保证缓冲区的互斥。
- 信号量S1表示生产消息数量,初值为0
- 信号量S2表示消息缓冲数量,初值为1
1 | 进程A(消费者) 进程B(生产者) |
- 进程A执行
P(S1)
时,需要等待进程B生产消息。 - 进程B执行
P(S2)
时,缓冲信号对应减1,当缓冲区信号一直没有被消息,或速度小于生产的速度时,这个时候缓冲区空间逐渐被占满,当缓冲信号对应为0时进程B进入等待队列,只有当进程A消费消息,执行V(S2)
释放缓冲区时进程B被唤醒继续生产消息。