操作系统——信号量机制

1.知识总览
操作系统——信号量机制
2.信号量机制
用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥,进程同步。

信号量其实就是一个变量(可以是一个整数,也可以是更复杂的记录型变量),可以用一个信号量来表示系统中某种资源的数量,比如:系统中只有一台打印机,就可以设置一个初值为1的信号量。

原语是一种特殊的程序段,其执行只能一气呵成,不可被中断。原语是由关中断/开中断指令实现的。软件解决方案的主要问题是由“进入区的各种操作无法一气呵成”,因此如果能把进入区,退出区的操作都用“原语”实现,使这些操作能“一气呵成”就能避免问题。

一对原语:wait(S)原语和signal(S)原语,可以把原语理解为我们自己写的函数,函数名分别为wait和signal,括号里的信号量S其实就是函数调用时传入的一个参数。
wait,signal原语常简称为P,V操作

3.整型信号量
用一个整数型的变量作为信号量,用来表示系统中某种资源的数量。

与普通整数变量的区别:对信号量的操作只有三种,即初始化,P操作,V操作。

我们看一道示例:
操作系统——信号量机制
通过上述示例我们发现:“检查”和“上锁”一气呵成,避免了并发,异步导致的问题。
但是整型信号量存在的问题是:不满足“让权等待”原则,会发生“忙等”。

4.记录型信号量
整型信号量的缺陷是存在“忙等”问题,因此人们又提出了“记录型信号量”,即用记录型数据结构表示信号量。
操作系统——信号量机制
操作系统——信号量机制
我们来道例题:
操作系统——信号量机制
例题剖析:
(1)假如刚开始CPU是为P0进程服务的,当它执行到wait原语时,首先执行的事情时value–,所以S.value会由2减为1。系统判断此时有打印机资源,将打印机资源分配给P0进程。

(2)当CPU又为P1进程服务时,执行wait原语,value–,所以此时S.value会由1减为0,之后系统会把打印机分配给P1进程。此时因为S.value=0,所以两台打印机全部分配给了某些进程,资源恰好分配完毕。

S.value+1后<=0,说明有进程在等待该资源

(3)CPU又为P2进程服务时,此时S.value会由0减为-1;因为value的值小于0,系统中已经没有多余的资源分配给P2进程了,所以P2进程会用一个阻塞原语,挂在打印机资源的等待队列里。

换句话说,S.value=-1,有1个进程在等待

(4)CPU又转向了P3进程,P3进程同P2进程一样,S.value=-2,主动执行阻塞原语,挂在等待队列里。

(5)P0进程使用完打印机之后,此时执行signal原语,使得value++,所以value会从-2变到-1,但是此时value值仍小于0,说明依然有进程在等待队列里等待。P0进程在signal原语之中会执行唤醒原语,用来唤醒等待队列中队头的原语(P2),P2进程会从阻塞队列进入就绪队列,并且P0将释放的打印机资源分配给P2。

(6)同样P2进程使用完打印机之后,也会执行signal原语,使得value++,此时value等于0,说明等待队列里还有一个进程正在等待。P2进程也会在signal原语之中会执行唤醒原语,用来唤醒等待队列中队头的原语(P3),P3进程会从阻塞队列进入就绪队列,并且P2释放的打印机资源会分配给P3进程。

(7)CPU再次执行P1进程,S.value+1后>0,说明已经没有进程在等待该资源,P1进程使用完打印机后将打印机资源释放。

(8)同样,CPU执行完P3进程后,S.value=2>0,P3进程将打印机资源释放…
操作系统——信号量机制
5.小节概述
操作系统——信号量机制