北航研究生课程_程序语言设计原理教程_第13章

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第13章程序的并发性和进程交互原语13.1基本概念程序与进程一个程序的一次执行叫做一个进程(process)就绪ready可执行代码装入内存立即可运行运行running执行进程阻塞blocked停止本进程执行,随时可恢复执行终止terminated停止,且不可恢复执行激活:创建一个进程并使之进入就绪或立即运行状态触发:使就绪或阻塞状态转入运行态中断:使运行的进程转入阻塞或终止态原语:程序语言中定义的例程名线程:创建子进程不另分配资源子进程:一个进程执行中再次创建的进程线程与进程计算模式及分类线程是共享资源的轻量级进程(lightweightprocess),它也有线程执行状态,也有其静态存储和局部变量。MS-DOSJavaUNIXWindowsNTSolarisMachOS/2原子动作原子动作是一次“立即”执行完的“顺序”动作。至于是否真正不再分就不一定了。原子动作一般定义在语句级的事件(event)上事件是本程序表示的状态有了变化例:PL/1的多任务PL/1的并发进程是任务TASK,它可以定义语句级的事件。P是一个进程,它并行执行Q进程,则P进程的正文可以写:DECLAREXEVENT:CALLQ(APT)TASK(X)//激活Q进程交互(1)独立进程两进程并行但不相关设进程为事件序列,若有C,K两并行进程,可表达为C‖K.其中:C={C1,C2…Cn}K={K1,K2,…Km}独立进程是两进程内任何事件Ci,Kj的执行都不依赖对方(2)竞争进程两进程竞争同一资源临界段(Criticalsection):据有并加工资源的代码段竞争进程一般形式是:C:loopK:loop入口协议入口协议临界段临界段出口协议出口协议非临界段非临界段endloopendloop入口协议一般是按所设共享变量判断能否进入,出口协议则改置正确值.为确保进程的确定性,利用共享变量“通信”协调(3)通信进程两进程有协议的信息交换设C,K定义如前,Ci必须先于Kj(Kj要用到Ci的结果)的执行,即其它事件先后无所谓,一定要保证Ci,Kj的执行顺序.•同步(synchronous)通信指两进程进度各不相同,但必须同步到达通信点.若一方未到,另一方等待,直至完成信息交换.交换后各自执行各自进程则为单向同步通信.如果交换后,发送方一直等待接受方执行的结果,拿回结果后再各自执行自己的进程为双向同步通信。•异步(asynchronous)通信一般要借助相当大的邮箱.两进程以各自速度执行,发送方有了信息投入邮箱,并继续执行自己进程.接受方在认为合适时从邮箱获取信息.一般不竞争邮箱且为单向通信,当然也可做成双向的。•定向/广播式通信所谓定向是发送方指明接受方.而广播式通信发送方只向公共信道发送信息,任何共享该信道的成员均可接受,所以是异步通信、单向的.13.2并发程序带来的问题(1)速度依赖并发程序执行结果,取决于顺序成分进程执行的相对速度.对于并发且有实时(realtime)要求的程序,执行结果还取决于绝对速度.并发程序调整相对速度的办法是延迟快进程.把进程挂起来(进入悬置态)待到指定条件满足才唤醒该进程.其基本原语是:await表达式do语句|进程(2)输入值依赖同一并发程序两组数据输入可能会有很大差别(3)不确定性顺序程序两次同样值的测试,一般情况下都是一致的.即所说的再现.并发程序因上述原因往往没有确定的结果值.对于有副作用的函数或表达式这种先后次序的差异影响则更大(4)死锁(deadlock)是一种状态,由于进程对资源有互不相兼容的要求而使进程无法进展.表现为:•受到排斥进程永远访问不到所需资源•循环等待进程资源分配链形成一封闭回路•无占先(nopreemption)进程无法放弃所占的、其它进程需要的资源.所谓占先,只要所据资源的进程未处于使用状态,另一优先级高的进程有了要求,则此资源被后者占去•把持(waitandhold)相互以占有对方资源为放弃已占资源的先决条件解决死锁的方法:•利用工具作静态死锁检测,可以避免或减少死锁出现的可能•或事前,让进程同时提出所有需要的资源,消除把持条件,或强行给资源排序,按此顺序满足要求,消除循环等待条件•或事前,为调度程序声明最大的资源需求•一旦出现,最笨的办法是重新启动,试换数据,找出原因改正之。事后重试解决•一旦出现,找出死锁地点,夭折某些事件或进程或设置检测点(5)死等(starvation)相互竞争的进程如果都满足进入某一资源条件,一般采用排队的先来先服务原则。相对最公平,但有的进程占用一种资源时间过长,致使其它资源长期闲置。适当地让它等待可以解放很多占时少而重要的进程,这样更公平。于是,除了先来先服务而外,在调度例程中约定或在条件中加入优先级表来达到此目的。调度程序则按此优先级和先来后到统一调度。如果优先级不当就会造成某些进程永远处于阻塞态,死等(但不是死锁)。死等是不公平调度引起的。解决的办法是在改变某些进程的优先级,在公平性和合理性上作某种折衷13.3并发程序的性质安全性(safety)是程序在执行期间不会出现异常的结果.对于顺序程序指其最终状态是正确的.对于并发程序指保证共享变量的互斥访问和无死锁出现活性(liveness)是程序能按预期完成它的工作.对于顺序程序指程序能正常终止.对于并发程序指每个进程能得到它所要求的服务;或进程总能进入临界段;或送出的消息总能到达目的进程,活性深深受到执行机构调度策略的影响公平性(fairness)指在有限进展的假设下没有一个进程处于死等状态.无条件公平性:调度策略如能保证每个无条件的原子功能均能执行弱公平性:在具有条件原子动作时,若条件原子动作能执行并依然保持无条件公平性,则为弱公平性强公平性:条件原子动作一定能执行,则为强公平性13.4低级并发机制和并发原语无论程序设计语言上层采取何种机制实现程序的并发,最底层不外乎创建进程(装入内存、初始化使之就绪);起动(或恢复)执行;阻塞(或叫冻结);停止执行;阻塞父进程创建子进程;撤销进程等六种操作。这六种操作更低层的实现是机器指令原语(premitive)是包含这些底层指令的例程。由于支持上层不同的并发机制,原语为了表述方便不同语言原语的差别在于所选组合指令的不同fork/multifork分股创建多个子进程并执行quit/join合股新创进程回到原进程wait(e)等待e为真执行本进程signal(e)示信e为真可切换至下一进程sleep(value)若value表达式满足,使所在进程阻塞wakeup(value)若value表达式满足,使所在进程唤醒(恢复执行)cobegins1‖s2‖…‖sncoend开始多个进程s1…sn并发执行coroutineN指定协例程NresumeM转入协例程Msend(Exp)to…将表达式值送至…进程received(V)from…接受来自…进程的消息,值由变量V传入例如:基于共享变量的同步机制(1)忙等待(busywait)设我们把指示变量叫做lock(锁),每次测试临界段是否锁定。竞争进程以测定进入条件(锁)保持协调地进入临界段,我们说它在语义上保证了条件同步。锁就是条件,协调就是同步请注意,此时未设同步原语。程度员也无法阻塞停止某个进程。如果有多个进程竞争进入临界段,则每个进程都要轮流测试锁。这就是著名的自旋锁(spinlock),其算法如下:programSPIN_LOCK:varLock:=false;processP1::loopwhennotlockdo∥条件同步lock:=true;∥入口协议临界段;lock:=false;∥出口协议P1的非临界段;enddo;endloop;endp1;processpn:endSPIN_LOCKprocessP2::loopwhennotlockdolock:=true;临界段;look:=false;P2的非临界段;enddo;endloop;endP2;上述算法如果在多处理器的条件下,进程严格同时到达,对资源的竞争变成对指示变量查询和更改的竞争,要取决于操作系统对公用主存储器的存取访问的排序。如果某进程进入循环且正在更新lock为true期间,第二个进程又访问了lock(为false),那么它也进入临界段。互斥得不到保证。为此,寻找以忙等待实现互斥同步的算法,从65年到81年有许多名家写了上百篇论文,最后peterson的算法(1981)获得满意的解。算法如下:programMUTUAL_EXCLUSIONVarenter1:Boolean:=false;enter2:Boolean:=false;turn:String:=“P1”;∥或赋初值“P2”processP1::loopenter1:=true;∥以下三行入口协议turn:=“P2”;whileenter2andturn=“P2”doskip;∥跳至循环末端临界段;enter2:=false;∥出口协议P1的非临界段;endloop;end;end.processP2::loopenter2:=true;turn:=“P1”;whileenter1andturn=“P1”doskip;临界段;enter1:=false;p2的非临界段;endloop;end;(2)信号灯Dijkstra首先理解到忙等待的低级和设计麻烦,提出了完整的信号灯(semaphores)理论(1968)。信号灯是一个非负整值变量s。在其上定义了两个操作P,V(取自荷兰语字头,即wait(等待)和signal(示信)。V操作发信号指示一个事件可以出现,P操作延迟所在进程直至某个事件已经出现:P(s):awaits0dos:=s-1;∥‘await’表达延迟的原语V(s):s:=s+1;ProgramMUTEX_EXAMPLE;varmutex:Semaphore:=1;processP1::loopP(mutex);∥入口协议临界段;V(mutex);∥出口协议P1的非临界段;endloop;endp1;processp2::loopP(mutex);临界段;V(mutex);P2的非临界段;endloop;end;end.例以信号灯实现的两进程互斥信号灯变量s,当只有一个资源时取值{0,1}就够了,此时称为二值信号灯。P,V操作很容易扩大到n个进程竞争一个临界段。也可以将二值信号灯劈开分别实施同步警卫功能。以下是生产者/消费者著名问题的同步解。programPRODUCER_CONSUMERvarbuf:TYPE;∥任意类型TYPEvarempty:sem:=1,full:sem:=0;∥两信号变量初始化processPRODUCER[i:1..J]::loopPRODUCER[i]产生一条消息m;deposit:P(empty);∥存入消息m的三个操作buf:=m;V(full);endloop;end;endPRODUCER_CONSUMER.processCONSUMER[j:1..N]::loopfetch:P(full);∥从buf取出消息m的三条操作m:=buf;V(empty);CONSUMER[j]取出这条消息m;endloop;end;将信号变量s一分为二(empty,full)简化了传递方向。称劈分二值信号灯(splitbinarysemaphore).这个算法保证了互斥,无死锁。将P,V操作扩充到多进程,多资源(多个临界段)也是很容易的。例如,我们可实现q个缓冲区的多生产、消费者问题。其算法如下:programPROD_CONSvarbuf[1...q],mi,mj:TYPE;varfront:=0,rear:=0;∥buf的下标变量varempty:sem:=q,full:sem:=0,∥劈分二值信号varmutexD:sem:=1,mutexF:semi=1;processPROD[i:1..M]:loopPROD[i]产生一条消息mideposit:P(empty);P(matexD);buf[rear]:=mi;rear:=rearmodq

1 / 27
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功