文章目录
2.3.1 进程同步、进程互斥
1、进程异步:
进程具有异步的特性,异步特性是指各并发执行的进程以各自独立的、不可预知的速度向前推进。
2、进程同步:
指为了完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调他们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。
3、进程互斥:
把一个时间段内只允许一个进程使用的资源称为临界资源。
-
对临界资源的互斥访问,可以在逻辑上分为四个部分
进入区 : 对访问的资源检查或进行上锁
临界区(段) : 访问临界资源的那部分代码
退出区: 负责解锁
剩余区: 其它处理 -
进程互斥需要遵循的原则
空闲让进、忙则等待、有限等待、让权等待
2.3.2 进程互斥的软件实现方法
1.单标志法
算法思想:两个进程在访问完临界区后会把使用临界区的权限交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予
代码如下(示例):
int turn = 0;//标志
//p0进程
while(turn!=0);//进入区
critical section;//临界区
turn = 1;//退出区,同时更改标志谦让给P1线程,让P1线程上处理机
remainder section;//剩余区
//p1进程
while(turn!=1);
critical section;
turn = 0;
remainder section;
可以实现互斥
存在的问题:p1要访问的话,必须p0先访问,违背:空闲让进原则
2.双标志先检查
算法思想:设置一个bool数组flag[]来标记自己是否想要进入临界区的意愿
注意:代码部分请先看懂第一个算法思想的代码,有助于更好的理解下面的代码
代码如下(示例):
bool flag[2]={false,false};
//p1进程
while(flag[1]);
flag[0]=true;
critical section;
flag[0]=false;
remainder section;
//p2进程
while(flag[0]);
flag[0]=true;
critical section;
flag[1]=false;
remainder section;
主要问题:当P1、P2进程是并发进行的,可能会违背忙则等待的原则,出现bug
3.双标志后检查
算法思想:设置一个bool数组flag[]来标记自己是否想要进入临界区的意愿,不过是先上锁后检查
bool flag[2]={false,false};
//p1进程
flag[0]=true;
while(flag[1]);
critical section;
flag[0]=false;
remainder section;
//p2进程
flag[0]=true;
while(flag[0]);
critical section;
flag[1]=false;
remainder section;
主要问题:当P1、P2进程是并发进行的,可能会两个同时上锁,都进不去,违反空闲让进和有限等待原则,出现bug
4.Peterson 算法
算法思想:结合了双标志算法和单标志算法,主动让对方先使用处理器。
bool flag[2]={false,false};
int turn=0;
//p1进程
flag[0]=true;
turn=1;
while(flag[1]&&turn==1);
critical section;
flag[0]=false;
remainder section;
//p2进程
flag[1]=true;
turn=0;
while(flag[0]&&turn==0);
critical section;
flag[1]=false;
remainder section;
遵循空闲让进、忙则等待、有限等待三个原则
但是未遵循让权等待的原则,有可能会出现“忙等”,一直占用CPU资源。
2.3.3 互斥锁
特性:
- 需要忙等,进程时间片用完才能下处理机
- 优点:等待期间不用切换进程上下文,多处理器系统中,若上锁的时间短,则等待代价很低
- 常用于多处理器系统,一个核忙等,其他核照常工作,并快速释放临界区
- 不太适合单处理机系统,忙等的过程中不可能解锁
2.3.4 用信号量机制实现进程互斥、同步、前驱关系
信号量:
信号量是一种变量,表示系统中某种资源的数量
一对原语:wait(S)原语和signal(S)原语,分别简称P(S)、V(S)
1、实现进程互斥
设置互斥信号量mutex,初值为1
对不同的临界资源需要设置不同的互斥信号量
PV必须成对出现
2、实现进程同步
保证一前一后的操作顺序
设置同步信号量S,初始为0
在“前操作”之后执行V(S)
在“后操作”之后执行(V)
3、实现进程的前驱关系
要为每一对前驱关系各设置一个同步变量
在“前操作”之后对相应的同步变量执行V操作
在“后操作”之前对相应的同步变量执行P操作
2.4.1 死锁的概念
1.什么是死锁
各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象。
2.进程死锁、饥饿、死循环的区别
死锁:
定义:各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象。
区别:至少两个或两个的进程同时发生死锁
饥饿:
定义:由于长期得不到想要的资源,某进程无法向前推进的现象。
区别:可能只有一个进程发生饥饿
死循环:
定义:某进程执行过程中一直跳不出某个循环的现象。
区别:死循环是程序员的问题
3.死锁产生的必要条件
- 互斥条件:多个进程争夺资源发生死锁
- 不剥夺条件:进程获得的资源不能由其它进程强行抢夺
- 请求和保持条件:某个进程有了资源,还在请求资源
- 循环等待条件:存在资源的循环等待链
4.什么时候会发生死锁
- 对系统资源的竞争
- 进程推进顺序非法
- 信号量的使用不当也会造成死锁