(2)同步一般一个进程相对于另一个进程的速度是不可预测的,也就是说,进程之间是异步运行的。为了成功地协同工作,有关进程在某些确定的点上应当同步它们的活动:一个进程到达了这些点后,除非另一进程已完成了某个活动,否则就停下来,以等待该活动结束。
j9 y$ e( @0 Z, g$ l! O(3)死锁当若干进程竞争使用资源时,可能产生下述情况:每个进程要求的资源都已被另一进程占用,于是也就没有一个进程能继续运行。这种情况称为死锁。
" t2 I. }3 g9 S. ^3.信号量与P,V操作& [" K" X6 v, P2 ~, ^/ [9 e1 [$ D
用顺序程序设计技术处理同步与互斥是十分困难的,为此引入信号量概念:信号量是一种特殊的变量,它的表现形式是一个整型变量及相应的队列:除了设置初值外,对信号量只能施加特殊的操作:P操作和V操作,P操作和V操作都是不可分割的原子运行,也称为原语(有时分别记为down()和up()或wait()和signal())。P操作的作用是将信号量S的值减1,若S的值成负数,则调用P操作的进程暂停执行,直到另一个进程对同一信号量作V操作。V操作的作用是将信号量S的值加1,若S的值小于等于0,从相应队列(关于S的队列)中选一个进程,唤醒它。
" ^ s# c7 ^+ E# w(1)互斥为了保护共享资源(如公共变量等),使它们不被多个进程同时访问,就要阻止这些进程同时执行访问这些资源的代码段,这些代码段称为临界区,这些资源称为临界资源。对临界资源访问的互斥要求可视作执行临界区的互斥要求。利用信号量可以方便地实现互斥临界区的管理要求。例如,令信号量mutex的初值为1,于是临界区就改写成下列形式的代码段。P(mutex);临界区V(mutex);由于mutex初值为1,P、V是原子操作,确实可以实现互斥。( E$ R( f# l% _0 d
(2)同步最简单的同步形式是:进程A在另一个进程B已到达点L2以前,不应前进到超过点L1。对此,可以令信号量proceed初值为0,实现这种同步的程序形式是: 进程A L1:P(proceed); … …进程B L2:V(proceed); … …更复杂一点的同步问题是单缓冲的生产者、消费者问题。
* G9 C9 {+ c, x/ e' m4.高级通信原语
- Q$ D' S- B h7 a- tP、V操作是用来协调进程间关系的,编程较困难而且没有信息交换,故常称为低级通信原语。此外,P、V操作必须有共享存储器,而高级通信原语则提供两种通信方式:有缓冲区的通信和无缓冲区的通信。9 b+ u( y$ `9 J+ {
(1)有缓冲区的通信方式中,有原语:
# d* }5 o4 b! P: g/ Z% W) y8 m/ @1 hWrite(Buffer_Name,Variable) 等缓冲区空再存入
# A6 a) N2 N" Y& |Read(Buffer_Name,Variable) 等缓冲区满再取出! a9 T2 z' D$ q. R2 W
(2)无缓冲区的通信,又称为消息传递,有原语:
- O# f1 X! u0 U0 t& X- |$ BSend(Who,Message) 发送消息给指定进程或一组进程- s# j V0 x: o6 z- s
Receive(Who,Message) 从约定进程接收消息有的系统还提供带标记的发送,有Send(Who,Message,Tag)用Tag可指定发送进程是否要等待接收进程取到内容以后再继续运行。一般接收者总是要等待消息到达后才继续运行。 |