第四章 互斥、同步与通信

目录

4.1并发进程(concurrent processes)

4.1.1前驱图的定义

4.1.2顺序程序及其特性

4.1.3并发程序及其特性

4.1.4程序并发执行的条件

4.1.5与时间有关的错误

4.2进程互斥(mutual exclusion)

4.2.1共享变量与临界区

4.2.2临界区与进程互斥

4.2.3进程互斥原则

4.2.4进程互斥的软件实现

4.2.5进程互斥的硬件支持

4.3进程同步(synchronization)

4.3.1进程同步的概念

4.3.2进程同步机制

4.3.3信号量与PV操作

4.3.4 条件临界区CCR(Conditional Critical Region)

4.3.5 管程(Monitor)

4.3.5.1 管程的提出

4.3.5.2 管程的形式

4.3.5.3 管程的语义

4.3.5.4 管程的使用

4.3.5.5 管程与PV操作的等价性

4.3.5.6 管程的嵌套调用问题

4.3.6 会合(rendezvous)

4.4进程高级通讯

4.4.1 进程高级通讯概念

4.4.2 进程通讯模式

4.4.3 直接方式

 4.4.4 间接方式(借助媒介)


4.1并发进程(concurrent processes)

4.1.1前驱图的定义

前趋图(precedence graph) 是有向无环图,图中每个结点表示一个语句、一个计算步骤、或一个进

程。结点间的有向边表示偏序或前趋(precedence relation)关系,记为“→”,→={(Pi,Pj)|Pj启动之

前Pi必须已经完成}。(Pi,Pj)∈→可记作Pi→Pj,称Pi是Pj的前趋,Pj是Pi的后继。

在前趋图中,没有前趋的结点称为初始结点,没有后继的结点称为终止结点 每个结点可以有一个

权重(weight),它可以表示该结点所包含的程序量或计算时间。

   

4.1.2顺序程序及其特性

1.内部顺序性:对于一个进程来说,它的所有指令是按序执行的

2.外部顺序性:对于多个进程来说,所有进程的活动是依次执行的

3.顺序程序的特性

顺序性:指令逐条执行

封闭性:不受其它程序及外界因素影响

可再现性:结果与推进速度无关

顺序性=>封闭性=>可再现性

4.1.3并发程序及其特性

1.内部并发性:指一个程序内部的并发性

2.外部并发性: 指多个程序活动的重叠执行(流水线)

3.并发程序的特性

间断性:多个程序交叉执行,通过中断实现程序切换

非封闭性:一个进程的运行环境可能被其它进程所改变,从而相互影响

不可再现性:重复运行同一程序不一定得到相同的结果

间断性=>非封闭性=>不可再现性

4.1.4程序并发执行的条件

1.目标:在失去封闭性的条件下,保持可再现性

2.R(pi)={a1,a2,……,am}表示程序pi在执行期间所需读取的所有变量的集合,称为“读集”

3.W(pi)={b1,b2,……,bn}表示程序pi在执行期间所需改变的所有变量的集合,称为“写集”

4.若两个程序p1,p2满足如下条件,则能够保持可再现性,因而可以并发执行。该条件是1966年

首先由Bernstein提出,故称为Bernstein条件

(简单来讲就是:p1要读的变量p2不会去写, p2要读的变量p1不会去写,并且 p1和p2不会同时

去写相同的变量。但允许p1和p2同时去读相同的变量) 

4.1.5与时间有关的错误

1.错误原因1:进程交叉执行(interleave,交错)

2.错误原因2:涉及公共变量(资源)

4.2进程互斥(mutual exclusion)

进程互斥是进程之间所发生的一种间接性相互作用,这种相互作用是进程本身不希望的,也是运行进程感觉不到的。进程互斥既可发生在相关进程之间,也可发生在不相关的进程之间。

4.2.1共享变量与临界区

1.共享变量(shared variable),多个进程都需要访问的变量(扩展到共享资源)

2.临界区域(critical region/critical section),访问共享变量的程序段

3.临界资源(critical resource),一次只允许一个进程使用的资源

4.2.2临界区与进程互斥

1.进程互斥:多个进程不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象称为进程互斥

2.互斥的定义包含二层涵义

(1)不允许多个进程同时进入关于同一组共享变量的相同的临界区域

(2)不允许多个进程同时进入关于同一组共享变量的不同的临界区域

4.2.3进程互斥原则

1.临界区互斥的框架(framework)

do
{
  entry section
  critical section(临界区)
  exit section
  remainder section(其余代码)
}while(true);

2.互斥性原则

mutual exclusion(互斥性):任意时刻只允许一个进程进入关于同一组共享变量的临界区—排他

3.进展性原则

progress(进展性):临界区空闲时,必须允许一个请求进入临界区的进程进入—效率

4.有限等待性原则

bounded waiting(有限等待性):一个请求进入临界区的进程在有限的等待时间内,必须获得进入该

临界区的机会—公平

4.2.4进程互斥的软件实现

1.Dekkel算法(课本91)

shared int flag[2]={false,false},turn=0/*or 1*/; 

do{  /*P1:*/
 flag[0]=1;
  while(flag[1]==1){
  if(turn==1){
   flag[0]=0;
      while(turn==1){skip();};
      flag[0]=1;}};
 临界区代码;
 turn=1;
 flag[0]=0;
 其余代码;
}while(true);


do{  /*P2:*/
 flag[1]=1;
  while(flag[0]==1){
  if(turn==0){
   flag[1]=0;
      while(turn==0){skip();};
      flag[1]=1;}};
 临界区代码;
 turn=0;
 flag[1]=0;
 其余代码;
}while(true);

2.Peterson算法(课本93)

shared bool flag[2]; //进入临界区的两种钥匙之一

shared int turn; //进入临界区的两种钥匙之二

//P1:
do{
 flag[0]=true;turn=1;
  while(flag[1]&&turn==1)
  {};
 临界区代码;
 flag[0]=false;
 其余代码;
}while(true);


//P2:
do{
 flag[1]=true;turn=0;
  while(flag[0]&&turn==0)
  {};
 临界区代码;
 flag[1]=false;
 其余代码;
}while(true);

3.Lamport面包店算法(课本94)

do{/*课本94*/
choosing[i]=1;
number[i]=max{number[0],number[1],...,number[n-1]}+1;
choosing[i]=0;
for(j=0;j<n;j++){
  while(choosing[j])
       skip;
  while((number[j]<>0)&&(number[j],j)<(number[i],i))
       skip:
  };
  临界区
  number[i]=0;
  其余代码
}while(1);

4.Eisenberg/Mcguire算法(课本95)

/*所采用的数据结构*/
enum stat{idle, want_in, in_cs};
stat flag[n]={idle};
int turn; //取0⁓n-1,初始时任意
flag[i]=idle; //进程Pi不想进入临界区
flag[i]=want_in; //进程Pi想进入临界区
flag[i]=in_cs; //进程Pi想进入或已进入临界区


/*算法*/
//pi进入
do{
  flag[i]=want_in;
  j=turn;
  while(j!=i){
          if(flag[j] != idle)j=turn;
          else j=(j+1)%n;};
  flag[i]=in_cs;
  j=0; 
  while((j<n)&&(j==i or flag[j]!=in_cs)){j++;};
}while(j!=n);
turn=i;

//临界区
//pi离开
j=(turn+1)%n;
while(flag[j]==idle)
{j=(j+1)% n;};
turn=j;
flag[i]=idle;

4.2.5进程互斥的硬件支持

1.硬件提供存储障碍语句

2.硬件提供原子变量

3.硬件提供“测试并设置”指令

4.硬件提供“交换”指令

5.硬件提供“开关中断”指令

4.3进程同步(synchronization)

进程同步是进程之间直接的相互作用的形式,是合作进程之间有意识地行为,只发生在相关进程之间。

4.3.1进程同步的概念

1.同步(synchronization),并发进程彼此协调推进速度,在某些点处互相等待或者唤醒的相互直接制约关系

2.一组进程靠并发得以正常执行,这种现象称为进程合作。参与合作的进程称为合作进程。

4.3.2进程同步机制

1.用于实现进程同步的工具称为同步机制,又称同步设施(synchronization mechanism)

2.同步机制要求

描述能力够用

可实现

高效

使用方便

4.3.3信号量与PV操作

1.信号量semaphore的定义

typedef semaphore struct{
       int value;
       PCB Pointer queue;};//进程控制块
     semaphore s;

2.P/V操作原语定义

//P操作原语的定义
void P(semaphore *s){
       s.value=s.value-1;
       if(s.value<0)
            asleep(s.queue);}

//V操作原语的定义
void V(semaphore s){
       s.value=s.value+1;
       if(s.value<=0)
            wakeup(s.queue);}

/*asleep(s->queue):执行此操作的进程的进程控制块进入队列s->queue的尾部,其状态由运行态转为等待态,系统转到处理器调度程序*/

/*wakeup(s->queue):将队列s->queue头部进程的进程控制块由该队列中取出,并将其排入就序列队,其状态由等待态转为就绪态*/

3.对于信号量的规定

必须置一次且只能置一次初值,初值一般>=0

只能执行P/V操作改变信号量,其它操作非法

4.几个有用的结论

当s.value>=0时,s.queue队列为空

当s.value<0时,|s.value|为队列s.queue的长度

当s.value初值=1时,一般用于进程互斥

当s.value初值=0时,一般用于进程同步

5.使用信号量解题的步骤

(1)认真读完题目中的每一个字

(2)找出问题中存在的所有竞争和合作

竞争=>互斥

合作=>同步

(3)找出问题中涉及的所有资源,一类资源一个信号量

(4)根据题意,确定每类资源初始的可用数量

6.生产者/消费者问题

(1)问题分析

(2)只考虑同步

(3)同时考虑同步和互斥

(4)代码实现

item product,x,buffer[k]; //环形缓冲区
semaphore S1,S2,M1,M2;
int in,out; //取值范围0,1,2,……,k-1


void producer(void){
  while(true){
    produce a product;
    P(S1);
    P(M1);
    buffer[in]=product;
    in=(in+1)%k;
    V(M1);
    V(S2);};}


void consumer(void){
  while(true){
    P(S2);
    P(M2);
    x=buffer[out];
    out=(out+1)%k;
    V(M2);
    V(S1);
    consume x;};}


void main(){
  S1.value=k;
  S2.value:=0;
  M1=M2=1;
  in=out=0;
  cobegin //并发执行多个进程
    P1: producer(); …… , Pm: producer();
    C1: consumer(); ……, Cn: consumer();
  coend;}

7. 读者/写者问题(详细见课本108)

 代码实现

void reader(void){
  P(mutex);
  read_count=read_count+1;
  if(read_count==1)P(r_w_w);
  V(mutex);
  <read operations>
  P(mutex);
  read_count:=read_count-1;
  if(read_count==0)V(r_w_w);
  V(mutex);}

semaphore r_w_w,mutex;
int read_count;

void writer(void){
  P(r_w_w);
  <write operations>
  V(r_w_w);}

void main(){
  read_count=0;
  r_w_w.value=1;  
  mutex.value=1;
  cobegin
    R1: reader(); …… , Rm: reader();
    W1: writer(); ……, Wn: writer();
  coend;}

8.障栅问题

(1)障栅(barrier)问题,一组进程并发执行,碰到障栅时将进入等待,直到全组进程都已到达障栅,之后这组进程一起越过障栅继续推进

(2)代码实现

semaphore mutex,barrier;
mutex.value=1;
barrier.value=0;
int count=0;
//进程Pi并发执行
P(mutex);
count=count+1;
if(count==n){
  for(i=1;i<=n;i++)
  V(barrier);};
  V(mutex);
  V(barrier);
//进程Pi继续并发执行

4.3.4 条件临界区CCR(Conditional Critical Region)

1.信号量与PV操作属于低级机制,条件临界区是一种高级的同步机制。

2.CCR与PV操作的等价性

用CCR可以实现PV操作

用PV操作可以实现CCR

3.条件临界区的实现效率是比较低的

4.3.5 管程(Monitor)

信号量+PV操作

管程

同步机制

对共享变量的操作及对信号量的PV操作分散在整个系统和各个进程中

将共享变量及对其所能执行的全部操作集中在一个模块中

优点

较为高效

较为灵活

可读性好

正确性易于保证

易于修改和维护

缺点

可读性差

正确性不易保证

不易修改和维护

较不灵活

效率较低

4.3.5.1 管程的提出

1.70年代初为克服分散式同步机制的缺陷,introduced by E.W.Dijkstra,C.A.R.Hoare,P.B.Hansen

2.基于管程的语言:Concurrent Pascal(Hansen) Modula(N.With) Mesa MOD* Concurrent Euclid XCY

3.20世纪70年代初流行一种构造操作系统的PCM方法

进程P:Process

类程C:Class

管程M:Monitor

4.PCM构造的OS是结构化的,便于理解、修改、维护

4.3.5.2 管程的形式
unction 函数名(形参表): 返回值类型;
  函数局部变量说明;
  begin 语句序列 end;
……
begin 共享变量初始化语句序列 end;
4.3.5.3 管程的语义

1.管程中的共享变量在管程外部不可见,外部只能通过调用管程中声明的外部过程/函数间接访问这些共享变量

2.为保证管程共享变量的数据完整性,规定管程互斥进入

3.管程中设有进程等待队列、相应的等待/唤醒机制,进程等待时释放管程的互斥权,唤醒进程时(比如P唤醒Q)

(1)P等待Q继续,直到Q退出或等待(Hoare)

(2)Q等待P继续,直到P退出或等待(Java)

(3)唤醒操作是管程中可执行的最后一个操作(Hansen)

4.3.5.4 管程的使用

1.生产者/消费者问题

type producer_consumer = MONITOR
  var B: array[0..n-1]of integer;
         count, in, out: integer;
         pq, cq: condition;
  define put_in, get_out;
  procedure put_in(item: integer);
    begin
      if(count=n)then wait(pq);
      B[in]:=item;
      in:=(in+1)%n; 
      count++;
      signal(cq);
    end;

procedure get_out(var item: integer);
    begin
          if(count=0)then
              wait(cq);
          item:=B[out];
          out:=(out+1)%n;
          count--; 
          signal(pq);
    end;
begin
    in:=0; out:=0; count:=0;
end;

2.读者/写者问题(写者优先)(部分代码)

//写者优先
type readers_writers = Monitor
  var rq,wq: condition;
         reading_count,write_count: integer;
  define start_read,finish_read,
             start_write,finish_write;    

procedure start_read;
begin
  if(write_count>0)then
     wait(rq);
  reading_count++;
  signal(rq);
end;


procedure finish_read;
begin
  reading_count--;
  if(reading_count=0)then
    signal(wq);
end;

procedure start_write;
begin
  write_count++;
  if(write_count>1)or
     (reading_count>0)
  then wait(wq);
end;

procedure finish_write;
begin
  write_count--;
  if(write_count>0)
  then signal(wq);
  else signal(rq);
end;

begin 
  reading_count:=0;
  write_count:=0;
end;
var rw:readers_writers;

读者:
rw.start_read;
{reading};
rw.finish_read;

写者:
rw.start_write;
{writing};
rw.finish_write;
4.3.5.5 管程与PV操作的等价性

用PV操作可以构造管程

用管程可以构造PV操作

1.用管程构造PV操作

管程

信号量与PV操作

var s:semaphore;

var s:semaphore;

init s(init_value);

s.value:=ini_value;

s.P;

P(s);

s.V;

V(s);

2.用PV操作构造管程

管程

信号量与PV操作

一个管程实例

一个入口等待队列var mutex:semaphore;初值1

一个紧急等待队列var urgent:semaphore;初值0

一个紧急等待计数变量var urgent_count:integer;初值0

一个条件变量

var c:condition;

一个信号变量var s:semaphore;初值0

一个计数变量var count:integer;初值0

等待操作

wait(c);

count:=count+1;

if(urgent_count>0)then begin

  urgent_count:=urgent_count-1;

  V(urgent); end;

else V(mutex);

P(s);

唤醒操作

signal(s);

if(count>0)then begin

  count:=count-1;

  urgent_count:=urgent_count+1;

  V(s);

  P(urgent); end;

进入管程

P(mutex);

离开管程

if(urgent_count>0)then begin

  urgent_count:=urgent_count-1;

  V(urgent); end;

else V(mutex);

4.3.5.6 管程的嵌套调用问题

问题:

        1.是否允许嵌套                

        2.若允许,如何处理互斥权

方法:

        1.禁止嵌套(Modula)                

        2.允许嵌套,等待时释放当前管程互斥权(并发Pascal)                

        3.允许嵌套,等待时释放所有管程互斥权                

        4.允许嵌套,调用时释放路经管程互斥权

4.3.6 会合(rendezvous)

1.会合指两个并发执行流汇集到一处

并发执行流: 调用和接受

均发生握手和同步

2.信号量和PV操作只适合具有统一内存的系统,不适合分布式环境

3.管程只适合具有统一内存的系统,不适合分布式环境

4.会合的图示

任务相当于进程

任务可以处于不同的主机中

被调用者代替调用者执行调用代码

Ada中会合的核心包括调用语句、接受语句accept和选择语句select

 

4.4进程高级通讯

4.4.1 进程高级通讯概念

1.进程通讯IPC(interprocess communication):进程之间的相互作用,包括互斥、同步及信息交换。

4.4.2 进程通讯模式

1.享内存模式(shared memory) :需要OS提供

公共内存

互斥同步机制

2.消息传递模式(message passing)

直接:进程=>进程

间接:进程=>信箱=>进程

4.4.3 直接方式

(1)对称形式(sender and receiver name each other)

 (2)非对称形式(only sender names receiver)

 1.有缓冲途径(消息传递模式、直接方式、非对称形式)

 2.无缓冲途径(消息传递模式、直接方式、非对称形式)

 4.4.4 间接方式(借助媒介)

1.相互通信的进程通过信箱来实现通信。

2.例子:

multi-sender<=>multi-receiver

multi-sender<=>one receiver

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

渊逸晟黯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值