一种资源
临界资源:进程不能共享的计算机资源,只分别单独访问的关系。比如打印机,一时刻只能有一个进程使用
两大核心点
互斥:竞争临界资源
同步:进程间的先后顺序,相互合作处理上的前后关系
四项基本原则
空闲让进:当需要的资源处于空闲的时候,任何进程都有资格使用它。
忙则等待:当有进程使用临界资源时,其他进程要等待
让权等待:不可进入临界区使用时,释放CPU,避免忙等
有限等待:在有限时间可以访问临界资源。避免“永远等待”
类成功的机制
硬件机制
禁止中断
使用禁止中断,原理时发生中断时系统不会发生CPU从一个进程切换到另外一个进程中的情况,其他进程不可能进入临界区执行。中断—>完成后—>中断结束。
简单,但是容易出现系统不知名故障,以及需要给普通用户禁止中断的权限。而且,只能用于单处理机系统,因为只能中断一个处理机的指令
TSL指令
TSL指令全称为Test and Set Lock 指令,意为检测并上锁。这种指令一般用于计算机多处理机系统,为专用的机器指令。
直接说缺点:1.存在空循环浪费计算机资源 2.可能存在现象
软件方式
面包店算法,容易在多进程时出现问题
锁机制
类似硬件方式的TSL。一样存在空循环浪费CPU资源
整型信号量
初始化操作
P/V两个原语操作,P表示测试,V表示增加。后面用wait()表示P,用singal()表示V
1 | wait(S){ |
还是违背了让权等待的原则 ,计算机一直以空循环消耗计算机资源
成功的机制
记录型信号量
例子:
1 | //信号量的数据结构 |
wait()通过判断减少一个资源是否可以继续进程,如果可以,进程继续进行,如果不行,那就将此进程放入睡眠队列中。
singal通过释放一个资源,然后判断在此之前计算机的资源有多少个,是否小于等于0,小于的情况就是唤醒睡眠队列下的队首进程利用刚刚释放资源。大于则说明之前计算机的资源充足
实现互斥的例子
A,B 两个进程需要计算机的打印机资源打印数据,两者运行时需要的时间以及次数不确定,此时
1 | semaphore mutex = 1; // 这是一个互斥信号量,一般设置为1,可以表示一个资源 |
两者比较完善地的实现了这两个进程之间的资源的互斥:
空闲让进?实现了
忙则等待?实现了
有限等待?实现了,只要每个进程不是长时间使用打印
让权等待?实现了,不存在CPU为一直运行的状态。
在互斥之中,信号量的初始值一般都赋值为1或者以上,表示一个资源。
实现同步的例子
进程A需要把中间数值放入单缓冲中,进程B需要取出进程A放入的中间数值。单缓冲一次只能一个进程操作,实现同步。
1 | semaphore empty = 1; //记录单缓冲中空位 |
在同步问题中 最为关键的便是确定前驱后继关系。信号初始值设为0表示此进程还没有完成,便于实现同步
经典类型问题
生产者消费者问题
哲学家思考问题
读写进程问题
理发店问题
完善机制-管程
管程定义:编译器设置
条件变量 直接调用阻塞