java多线程上篇(二) -- 进程的控制、同步
一、进程的控制
进程的基本数据信息是操作系统控制管理进程的数据集合,这些信息就是用来控制进程的,此处我们说的进程控制就是进程的管理。
1. 进程的创建
2. 进程的终止
3. 进程的阻塞与唤醒
4. 进程的挂起与激活
小结
进程的控制就是操作系统对进程的主要管理工作,最重要的就是状态的切换维护。每种状态都有不同的引发事件,每种状态又有各自不同的处理步骤和过程,整个进程控制主要就是涉及这些内容。上面主要就是对这些状态进行简单的描述,以更好地对“进程的控制”这个概念有一个透彻的理解上图中的思维导图是进程控制的核心必须要理解:操作系统对于进程的控制就是对于这些状态的切换,以及切换所需要的数据维护。
二、进程的同步
(一)、进程同步概念
1.1 临界资源
一旦有对资源的共享,就必然涉及竞争限制
所以尽管A进程和B进程轮流获得时间片运行,但是当需要访问临界资源时,一旦有一个进程已经开始使用,另外的进程就不能进行使用,只能等待。
1.2 两种制约关系
既然资源访问有限制,到底有哪些场景是需要同步处理的?也就是何时会出现资源冲突?
看得出来,其实同步要解决的问题根本就是竞争,间接关系是赤裸裸的的竞争,共享同一个I/O就是一种竞争,尽管他们看似好像没有什么关系
直接的制约关系,源于进程间的合作,某种程度上来说也是一种竞争,只不过是有条件的竞争,他们共享缓冲区,当缓冲区满时只能是消费者可以运行,生产者需要阻塞,这可以认为缓冲区满这种情况下,消费者独占了缓冲区,生产者不能使用了,不过这种情况下还是说成合作比较容易理解
所以,要么是因为共享资源带来的竞争,要么就是相互合作带来的依赖。
1.3 临界区
有了临界资源的概念,就很容易理解临界区的概念,在程序中,所有的操作都是通过代码执行的,访问临界资源的那段代码就是临界区
以打水为例,所以在还没到井口,就要画一个大圈,不允许第二个人进入范围,“请站在安全黄线内”这句话熟悉么?这就是临界区。
1.4 同步规则
四种同步规则: 1. 空闲让进 2. 忙则等待 3. 有限等待 4. 让权等待
空闲让进:对于临界资源没有被使用,则谁来都可以直接使用。
忙则等待:这个就是上面的对立,如果临界资源被使用,后者就需要进行等待。
有限等待:保证在有限时间内,进入临界区,而不是一直憨憨的傻等。
让权等待:如果一直进入不了临界区,就要释放处理机,让别人进入,不能一直占着没有结果。比如超市付钱,一直连不上网,无法付钱,所以你必须让后面的人来付款,不能浪费时间和资源。
有限等待和让权等待的共同特性是必须保证有条件的退出以给其他进程提供运行的机会。简单说就是有限时间内你就要走开,你得不到更要走开,你即使能得到但是时间太久也得先让一下别人
临界区的设置就是安全黄线的设置,同步规则其实就是临界区两条黄线进出规则
对于临界区,还可以进一步细分出来进入区和退出区以及剩余区
(二)、临界区算法
Peterson算法
为了进入临界区,进程pi首先设置flag[i]为true;并且设置turn为j;显然,根据while的条件,只有flag[j] == false 或者turn == i 时,pi可以进入临界区也就是如果我想进入的话,当对方不想进入或者当前允许我进入时,我就可以进入临界区显然,如果只有一个进程想要进入,那么如上所述,对方不想进入时,可以进入临界区,符合空闲让进
(三)、同步方式之信号量
1965年,荷兰学者Dijkstra 提出的信号量(Semaphores)机制是一种卓有成效的进程同步工具。
临界区算法的原理可以让多进程对于临界区资源的访问串行化;信号量机制允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。-- 当它的值大于0时,表示当前可用资源的数量;-- 当它的值小于0时,其绝对值表示等待使用该资源的进程个数。
一般来说,信号量S>=0时,S表示可用资源的数量。
执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。
而执行一个V操作意味着释放一个单位资源,因此S的值加1;若S<=0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。
一、整型信号量
最初信号量机制被称之为整型信号量
最初由Dijkstra 把整型信号量定义为一个用于表示资源数目的整型量 S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作(Atomic Operation) wait(S)和 signal(S)来访问。
wait表示资源申请:如果S小于等于0(资源不足)等待,如果满足那么将会进行S-1,也就是申请资源
P、V操作也称之为操作原语,就是指原子操作。(原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败)
简单来说: p操作(wait):申请一个单位资源,进程进入
PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:
②如果S<=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
V(S): ①将信号量S的值加1,即S=S+1;
②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。
使用PV操作实现进程互斥时应该注意的是:
(1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。
(2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。
(3)互斥信号量的初值一般为1。
优缺点
优点:效率高。
缺点: 1. 不可被中断。由于PV操作是原子操作,因此若程序在PV操作间隙出现异常进而中断PV操作,那么会造成该程序无法恢复信号量,进而导致一直锁住某块临界资源,造成程序死锁,永远无法访问。
2. 我们说,一个好的进程调度,需要满足这四个条件:闲则让进,忙则等待,有限等待,让权等待(见名词表释义),然而整型信号量无法实现让权等待,导致处理器性能降低。
二、记录型信号量
定义:一个由两部分组成的结构体。其一为整型数值(就是整型信号量),其值为正数时用于记录当前允许进入临界区的进程数量,为负数时,记录阻塞队列中进程数量;其二为链表,用于记录当前想要进入临界区的进程。
鉴于整型信号量机制中的“忙等”情况,演化出来记录型信号量,如果进程无法进入临界区,那么进入等待释放CPU资源,并且通过一个链表记录等待的进程。
semaphore {
value:int value;
L:进程等待链表(集合);
}
相对应整型信号量中的wait(S) 和 signal(S)可以描述为:
wait(S):
var S = semaphore;
S.value=S.value-1;
if S.value<0 then block(S.L); signal(S):
var S = semaphore;
S.value=S.value+1;
if S.value<=0 then wakeup(S.L);
上面的操作中,均定义了一个semaphore类型的变量S
- 如果执行 wait 操作,先执行资源减一,如果此时S.value<0,说明在申请资源之前(S.value-1),原来的资源就是<=0,那么该进程阻塞,加入等待队列L中
- 如果执行 signal 操作,先执行资源加一,如果此时S.value<=0,说明在释放资源之前(),原来的资源是<0的,那么将等待链表中的进程唤醒
- 当申请资源时,先进行S.value-1,一旦资源出现负数,说明需要等待,S.value的绝对值就是等待进程的个数,也就是S.L的长度
- 当资源恢复时,先进行S.value+1,已经有人释放资源了然而资源个数还是小于等于0,说明原来就有人在等待,所以应该去唤醒
block 和 wakeup 也都是原语,也就是原子操作。block原语,进行自我阻塞,放弃处理机,并插入到信号量链表S.L 中;wakeup原语,将S.L链表中的等待进程唤醒。
如果 S.value的初值为 1,表示只允许一个进程访问临界资源,此时的信号量转化为互斥信号量,用于进程互斥。(效果就如同Peterson算法了)
三、AND型信号量
针对于临界区算法或者是整型信号量或者是记录型信号量是针对各进程之间只共享一个临界资源而言的。
process A: process B:wait(D); wait(E);wait(E); wait(D);
process A: wait(D); 于是D=0process B: wait(E); 于是E=0process A: wait(E); 于是E=-1 A阻塞process B: wait(D); 于是D=-1 B阻塞
四、信号量集
1. Swait(S,d,d)。此时在信号量集中只有一个信号量 S,但允许它每次申请 d 个资源,当现有资源数少于d时,不予分配。
2. Swait(S,1,1)。此时的信号量集已蜕化为一般的记录型信号量(S>1时)或互斥信号量(S=1 时)。
3. Swait(S,1,0)。这是一种很特殊且很有用的信号量操作。当 S≥1 时,允许多个进程进入某特定区;当 S 变为 0 后,将阻止任何进程进入特定区。换言之,它相当于一个可控开关。
五、小结
临界区机制通过算法控制进程串行进入临界区,而信号量机制则是借助于原语操作(原子性)对临界资源进行访问控制
---- 整型信号量机制可以处理同一共享资源中,资源数目不止一个的情况---- 记录型信号量对整型信号量机制的“忙等”进行了优化,通过block以及weakup原语进行阻塞和通知---- AND型信号量机制解决了对于多个共享资源的同步---- 信号量集是对AND的再一次优化,既能够处理多个共享资源同步的问题,还能够设置资源申请的下限,是一种更加通用的处理方式
(四)、同步方式之管程
(一)、管程的定义
(二)、管程的特点
(三)、条件变量
上面可以用简单的例子解释。A在用厨房,突然临时有事,要停止做饭 离开厨房。但是他把厨房锁住,钥匙拿走,不允许排队的人做饭,必须等待他回来做完。那他什么时候回来?这个太占用资源了,所以需要找个方法解决。如下。
接着上面例子扩展理解。1. 加入A在厨房(管程)做饭,其他人在外面等着(阻塞队列),此时A来一个电话,临时有事(x的条件),需要停止做饭(阻塞),离开厨房(管程),这个时候可以让排队的人进来做(唤醒)。此时A就是阻塞状态。这个是x.wait。2. 过会A把事情处理完了回来,就让此时正在做饭的兄弟暂停(阻塞),让A开始继续做放(唤醒)。这个是x.signal个人理解,如有不符,敬请谅解!
总结
感谢 :https://www.cnblogs.com/noteless/p/10350253.html#16
最新文章
- android bluetooth蓝牙移植
- 最短路--floyd算法模板
- ThinkPHP连接sql server数据库
- App can入门
- eclipse启动tomcat时设置端口
- FZU2132 - LQX的作业(概率论)
- java.lang.NoSuchFieldError: deferredExpression解决
- C# KeyValuePair<;TKey,TValue>;与Container
- Spring Boot Admin Reference Guide
- win8 64位使用plsql developer连接oracle数据库问题
- POJ 3602 Typographical Ligatures
- VS 2012 单元测试简单配置
- PHP ckeditor富文本编辑器 结合ckfinder实现图片上传功能
- js写插件教程
- 基于web的网上书城系统开发-----需求分析
- c++三种继承方式public,protect,private
- OpenCV-Python入门教程1-图片
- Rop框架学习笔记
- jdreact转换为H5注意事项
- js动态生成水印
热门文章
- Readiness probe failed:connection refused
- git add 不能提交 vendor下面的一个文件夹
- 10月清北学堂培训 Day 6
- ftp连接
- Jenkins 更新 jenkins.war的方法
- Cesium中常用的一些地理数据文件 以及数据相关的东西
- MATLAB中图像的基本操作
- JAVA书写格式规范
- 015-命令行下载安装brew
- .The server quit without updating PID file (/var/lib/mysql/pc.pid).