操作系统笔记-2.3.4.1 信号量机制
王道操作系统笔记视频链接2.3.4.1 信号量机制知识总览信号量机制整型信号量记录型信号量复习回顾思考之前学习的这些进程互斥的解决方案分别存在哪些问题进程互斥的四种软件实现方式单标志法、双标志先检查、双标志后检查、Peterson算法进程互斥的三种硬件实现方式中断屏蔽方法、TS/TSL指令、Swap/XCHG指令在双标志先检查法中进入区的“检查”、“上锁”操作无法一气呵成从而导致了两个进程有可能同时进入临界区的问题所有的解决方案都无法实现“让权等待”1965年荷兰学者DIjkstra提出了一种卓有成效的实现进程互斥、同步的方法——信号量机制信号量机制用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作从而很方便的实现了进程互斥、进程同步。信号量其实就是一个变量**可以是一个整数也可以是更复杂的记录型变量可以用一个信号量来表示系统中某种资源的数量**比如系统中只有一台打印机就可以设置一个初值为1的信号量。原语是一种特殊的程序段其执行只能一气呵成不可被中断原语是由关中断/开中断指令实现的。软件解决方案的主要问题是由“进入区的各种操作无法一气呵成”因此如果能把进入区、退出区的操作都用“原语”实现使这些操作能“一气呵成”就能避免问题。第1点中的一对原语指的是wait(S)原语和signal(S)原语。可以把原语理解为我们自己写的函数函数名分别为wait和signal括号里的信号量S其实就是函数调用时传入的一个参数。wait、signal原语常简称为P、V操作来自荷兰语proberen和verhogen。因此做题的时候常把wait(S)和signal(S)两个操作分别写为P(S)、V(S)总结信号量是一种变量用来表示系统中某种资源的数量可以用系统中的一对原语wait与signal来对信号量进行操作信号量可以根据其类型分为整型信号量和记录型信号量整型信号量用一个整数型的变量作为信号量用来表示系统中某种资源的数量。与普通整数变量的区别对信号量的操作只有三种即初始化、P操作、V操作例子某计算机系统中有一台打印机int S 1; // 初始化整型信号量S表示当前系统中可用的打印机资源数 void wait (int S) { //wait 原语相当于“进入区” while (S 0); //如果资源数不够就一直循环等待 SS-1; //如果资源数够就占用一个资源 } void signal (int S) { //signal 原语相当于“退出区” SS1; //使用完资源后在退出区释放资源 } 进程P0: ... wait(S); //进入区申请资源 使用打印机资源... //临界区访问资源 signal(S); //退出区释放资源 ...特点优点类似先检查后上锁但是这里是原语一气呵成避免了并发、异步导致的问题缺点不满足“让权等待”原则会发生“忙等”补充问为什么原语有个while循环又不可被中断会不会导致一直占用处理器卡死答来自视频确实不太严谨但是很多经典教材都这么写的姑且认为没问题。答来自deepseek会所以该代码只能作为理论上的概念引入实际系统中绝不可能直接这么写否则系统一遇到资源竞争就会立刻卡死这也是早期“整型信号量”机制被淘汰的原因。记录型信号量整型信号量的缺陷是存在“忙等”问题因此人们又提出了“记录型信号量”即用记录型数据结构表示的信号量。代码示例/*记录型信号量的定义*/typedefstruct{intvalue;//剩余资源数structprocess*L;//等待队列}semaphore;/*某进程需要使用资源时通过 wait 原语申请*/voidwait(semaphore S){S.value--;if(S.value0){block(S.L);// 如果剩余资源数不够使用block原语使进程从运行态进入阻塞态// 并把其挂到信号量S的等待队列即阻塞队列中}}/*进程使用完资源后通过 signal 原语释放*/voidsignal(semaphore S){S.value;if(S.value0){wakeup(S.L);// 释放资源后若还有别的进程在等待这种资源// 则使用wakeup原语唤醒等待队列中的一个进程// 该进程从阻塞态变为就绪态}}补充个人总结为什么wait的判断条件是S.value 0而signal是S.value 0答如果value无限大也就是资源十分充足wait中就不会有进程进入阻塞所以前者的S.value 0是资源不够的情况下才有进程进入阻塞。后者在判断前S.value所以此时S.value 0就代表还有进程阻塞就需要进行唤醒。注意这里只针对每次申请和释放都是一个资源如果同时申请、释放多个资源那这个代码就有些问题。比如总共5个A要3个B要3个B阻塞资源数为-1A释放后资源数为2此时就不会唤醒B了。其实原因也很简单之前是S.value所以条件是S.value 0之前的改成S.valuekk0条件就应该改成S.value k-1Pi进程用于第4点的例子 ... wait(S); //进入区申请资源 使用打印机资源... //临界区访问资源 signal(S); //退出区释放资源 ...例子某个计算机系统中有2台打印机则可在初始化信号量S时将S.value的值设为2队列S.L设置为空。假设有P0到P3总共4个进程如Pi所示四个进程依次上CPU运行过程如下P0上处理机S.value1S.L{}P1上处理机S.value0S.L{}P2上处理机S.value-1S.L{P2}P3上处理机S.value-2S.L{P2,P3}P0上处理机S.value-1S.L{P3}P1上处理机S.value0S.L{}P2上处理机S.value1S.L{}P3上处理机S.value2S.L{}总结在考研题目中wait(S)和、signal(S)也可以记为P(S)、V(S)这对原语可用于实现系统资源的“申请”和“释放”。S.value的初值表示系统中某种资源的数目。对信号量S的一次P操作意味着进程请求一个单位的该类资源因此需要执行S.value–表示资源数-1当S.value0时表示该类资源已分配完毕因此进程应调用block原语进行自我阻塞当前运行的进程从运行态→ \to→阻塞态主动放弃处理机并插入该类资源的等待队列S.L中。可见该机制遵循了“让权等待”原则不会出现“忙等”现象。对信号量S的一次V操作意味着进程释放一个单位的该类资源因此需要执行S.value表示资源数1若1后仍是S.value0表示依然有进程在等待该类资源因此应调用wakeup原语唤醒等待队列中的第一个进程被唤醒进程从阻塞态→ \to→就绪态知识回顾与重要考点整型信号量比较容易考察的是它存在的问题——不满足“让权等待”可能出现“忙等”现象记录型信号量是操作系统这门课最重要的知识点大题小题都有很高概率考察记录型信号量能够实现进程互斥、进程同步这部分知识点会在下一小节进行讲解。

相关新闻

最新新闻

日新闻

周新闻

月新闻