同步与互斥

在多道程序系统中,由于进程并发,资源共享与进程协作,使得进程间可能产生两种形式的制约:

1、间接相互制约:源于资源共享,如果进程ab共享一种资源,如果a请求资源时发现进程b正在访问这种资源,那么进程a就进入阻塞队列,当进程b释放资源,进程a被唤醒到就绪状态

2、直接相互制约:源于进程协作,如果进程a通过单项缓冲向进程b提供数据,当缓冲为空进程b得不到数据而进入阻塞队列,一旦a进程的数据进入缓冲,进程b被唤醒,反之,缓冲满了,则a被阻塞,只有b取走数据后a才能被唤醒

进程同步:同步进程的直接相互制约

进程互斥:源于间接相互制约,资源共享,保证每次只有一个进程访问共享资源

临界资源:一次只允许一个进程访问的资源

临界区:访问临界资源的那段程序

同步准则:空闲就进,遇忙则等,有限等待(对要求进入的进程,应在有限的时间内进入,避免死等),让权等待(对于等待进程要立即释放处理机,避免进程忙等)

实现临界区互斥的基本方法:

1、单标志位:

进程1:

while(turn!=0);

do_something

turn = 1;

进程2

while(turn!=1);

do_something

turn = 0;

算法设置了一个标志位,0时候允许进程1进入临界区,1时候运行进程2进入临界区,弊端:了,两个进程必须交替进入临界区

2、双标志位先检查:

while(flag[j]);1

flag[i] = true;3

do_something

flag[i] = false;

进程2

while(flag[i]);2

flag[j] = true;4

do_something

flag[j] = false;

优点可以连续使用,确定如果按照1234的顺序执行,可能两个进程同时进入临界区

2、双标志位后检查:

flag[i] = true;

while(flag[j]);

do_something

flag[i] = false;

进程2

flag[j] = true;

while(flag[i]);

do_something

flag[j] = false;

先置位后检查,可以克服上个算法的缺点,但是有可能两个进程先后置位后双方都不能进入临界区

4、peterson algorithm

flag[i] = true;

turn = j;

while(flag[j]&&turn == j);

do_something

flag[i] = false;

进程2

flag[j] = true;

turn = i;

while(flag[i]&&turn == i);

do_something

flag[j] = false;

增加一个标志位turn表示不允许某进程进入临界区,可以使得只有一个进程进入临界区


完全用软件方式实现同步和互斥机制,有很大的局限性,用硬件支持的原子性指令(如ts指令和swap指令),可以使操作不会打断,可以解决临界区问题

1、检测和设置ts指令

一个bool值false的时候没有进程使用,true的时候有进程使用

while TS(&lock);

do_something

lock = false;

2、swap指令

key = true;

do

{

swap(&lock,&key);

}while(&key);

do_something

lock = false;

硬件方法的有点:适用于任意数目的进程,简单容易验证正确性,如果有多个临界区,只要为每个临界区设立一个bool变量

缺点:等待要耗费处理机时间,不嫩做到让权等待,可能出现饥饿,可能出现死锁

信号量

之前提到的算法都是平等进程间的协商机制,操作系统可以从进程管理者的角度来处理互斥问题,信号量就是一种有效手段

信号量是一个荷兰科学家1985年提出,p,v都是荷兰语的首字母,由一个二元组组成,一个int初始非负,一个初始状态为空的等待队列(pcb队列)int大于零表示资源个数,小于零表示排队进程数,p为减一,v为加一。

p操作:

int--;申请一个资源

if(int<0)表示没有空闲资源

{

进程进入等待队列

阻塞进程

}

v操作

int++;释放一个资源

if(int<=0)表示有进程处于阻塞状态

{

从等待队列取出一个进程

进程进入就绪队列,唤醒一个进程分配处理机

}

互斥模型实现:

typedef int semaphore;

semaphore mutex = 1;

p1

{

p(mutex);

do_something

v(mutex);

}

p2

{

p(mutex);

do_something

v(mutex);

}

同步模型(p1生产,p2消费)

typedef int semaphore;

semaphore mutex = 0;

p1

{

do_something

v(mutex);

}

p2

{

p(mutex);

do_something

}

管程:用信号量和pv操作,信号量的操作分散在进程中,易读性,维护性,正确性难以保证

管程定义:共享资源用数据结构表示时候,资源管理程序可以定义一组过程处理资源,把这组过程和数据结构叫做管程,3部分共享数据,过程方法和初始化,任何时候只有一个进程可以在管程中运行,管程需要编译器支持


经典的同步互斥问题:


死锁:两个以上的进程无限期的等待不会发生的条件,处于一种停滞状态,产生死锁的原因:推进顺序不当,对互斥资源分配不当

四个必要条件:

互斥条件(一次只能有一个进程使用资源),占用并请求(部分占用,还要请求更多资源),非剥夺条件,循环等待(请求资源的进程形成了循环)

处理策略:

1、忽略:鸵鸟算法

2、死锁检测和恢复:根据保有的资源信息定期检查是否有死锁(有向图法和矩阵法),然后处理1、资源剥夺(挂起进程释放资源)2、进程撤销(撤销占用资源多或者代价小的进程),进程回退(如果有进程历史信息,可以回退到无死锁状态),重启系统。

3、死锁避免:银行家算法,规定安全顺序和非安全顺序,安全一定不会死锁,不安全可能有死锁

4、预防死锁:打破四个必要条件


由于锁获取顺序产生的死锁:

thread1:

a.clock()

b.clock()

thread2

b.clock()

a.clock()

顺序不同造成死锁,处理方法1改变顺序

2一次获得两个锁

用getlock(a,b)伪代码一次获得两个锁

在windows里面有WaitForMultipleObjects系统调用

线程之间的关系有三种:无关系,共享,同步。

进程之间通信、协调、通过一些事件通知或等待互斥锁的释放方面,不同的平台所支持的方式不一样

多进程共享数据代价大于线程,因为涉及序列化与反序列化的开销。一些ipc手段是单机os支持的,到了多机的分布式系统上要自己实现,而且性能有问题,网线带宽问题







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值