全知识整理目录
操作系统整理的目录,包括了整理的所有操作系统的知识。
概述
为什么要引入信号量机制呢?
首先,信号量机制是为了解决进程互斥与同步的问题。
那么互斥与同步存在什么问题呢?
进程互斥有4种软件实现办法(单标志法,双标志法,双标志后检查法,Peterson算法)
进程互斥有3种硬件实现办法(中断屏蔽法,TS/TSL指令,Swap/XCHG指令)
存在了一些问题:双标志检查法,检查和上锁,无法一气呵成,从而导致两个进程都有可能同时进入临界区。
其他的所有办法,都违反了“让权等待”
思维导图
这一章比较重要,很多地方都要使用,所以看看思维导图,能更快的回顾。
什么是信号量机制 ?
作用:用户可以通过使用操作系统,提供的一对原语来对信号量进行操作,从而很方便地实现了进程互斥,进程同步。
理解:wait(S)原语和signal(S)原语,可以把原语理解为函数,括号里面的信号量S,就是调用函数时,传入的参数。信号量 S可以是一个整数,也可以是复杂的记录型变量。例如办公室有一台打印机,想要用S来表示打印机,那么S=1。
整型信号量
如果,还是这个问题,办公室只有一台打印机。代码如下:
int S = 1; //表示信号量
void wait(int S){ //wait原语,相当于进入区
while(S <= 0); //如果资源S不够,那么一直等待
S=S-1; //如果资源够,则占用一个资源
}//上面是检查和上锁
void signal (int S){ //signal相当于退出区
S=S+1; //使用完资源,释放一个资源
}//上面是开锁
进程P0
。。。
wait(S);
使用打印机
signal(S);
释放打印机
。。。以此类推
记录型信号量
显然,前面的整型信号量,如果一直拿不到资源,就会陷入忙等的情况。
所以,记录型信号量,可以说是对整型信号量的改进。
//记录型信号量的定义
typedef struct {
int value; //剩余资源数
struct process *L; //等待队列
} semaphore;
//wait原语申请
void wait (semaphore S){
S.value--; //S.value表示,资源数
if(S.value < 0){
block (S.L); //如果剩余资源不够,使用block阻塞进程
}
}
//signal原语释放资源
void signal (semaphore S){
s.value++;
if(S.value <= 0){
wakeup(S.L); //释放之后,如果还有别的进程还在等待这个资源,则使用wakeup唤醒。
}
}