在整型信号量中
- 操作定义与实现:
wait(S)
操作中,先执行S = S - 1
,请求一个单位资源。然后判断S
是否小于 0 ,若小于 0 ,进程进入忙等状态,持续循环检查,直到S
大于等于 0 ,才能获取资源继续执行。
signal(S)
操作则是执行S = S + 1
,释放一个单位资源,若此时有进程在等待资源(S
小于等于 0 ) ,理论上应该唤醒等待进程,但整型信号量没有专门的等待队列,只是通过循环等待的进程检测到S
大于等于 0 后自行继续执行 。
- 存在的问题:
整型信号量的wait
操作会出现 “忙等” 现象 ,即进程在等待资源时持续占用 CPU 资源不断循环判断,造成 CPU 资源浪费 。比如有多个进程竞争一个资源,等待的进程会一直占用 CPU 检查资源是否可用,而不能去做其他事 。
在记录型信号量中
- 操作定义与实现:
wait(S)
操作先将S->value
减 1 ,请求资源。若S->value
小于 0 ,调用block(S->list)
,将进程阻塞并放入信号量S
的等待队列S->list
中 ,释放 CPU 资源。
signal(S)
操作先将S->value
加 1 ,释放资源。若S->value
小于等于 0 ,说明等待队列中有进程等待,调用wakeup(S->list)
,从等待队列中唤醒一个进程 ,让其进入就绪态等待调度执行 。
- 改进之处:
记录型信号量通过引入进程等待队列和block
、wakeup
操作,解决了整型信号量的 “忙等” 问题 。当资源不足时,进程不再是忙等,而是进入阻塞状态,不占用 CPU 资源,直到被唤醒 。