PV和管程 操作系统教程课后习题

PV和管程 操作系统教程课后习题

  1. 有一个电子转帐系统共管理 10000 个帐户,为了向客户提供快速转帐业务, 有许多并发执行的资金转帐进程,每个进程读取一行输入,其中,含有:贷方帐 号、借方帐号、借贷的款项数。然后,把一款项从贷方帐号划转到借方帐号上, 这样便完成了一笔转帐交易。写出进程调用 Monitor ,以及 MOnitor 控制电子 资金转帐系统的程序。
TYPE lock-account = monitor
VAR use : array [1 … 10000] of Boolean ; / *该帐号是否被锁住使用标志
S :array [ 1 … 10000 ] of condition ; / *条件变量
DEFINE lockaccount unlockaccount / *移出过程
USE wait , signal , check , release ; / *移入过程
begin
for i:= 1 ; to 10000 do use [i]:=false ;
end .
procedure lockaccount ( var i,j : integer ){
    Check ( IM )
    if i > j then begin
    Temp:= i ;
    i : = j ;
    j : = temp ;
    end ; / *层次分配,先占号码小的账号否则可能产生死锁
    if use [i] 
    	wait(s[i].lockaccount,IM ) ;
    else 
    	use [ i ] :=true ; / *锁住 account ( i )
    if use[j] 
		wait ( s[j].lockaccount,IM);
    else 
    	use [j]:=true ; / *锁住 accounto )
    Release ( IM ) ;
}

Proeedure unfockaccount ( var i:sinteger ; ){
    Check ( IM ) ;
    use [ i ] : = false ;
    signal(s[i].lock-account , IM ) ;
    Release ( IM ) ;
}

Process transfer account{
    begin
    input a information line ;
    get the account number i,j and 还款数 x ;
    Lock-account.lockaccount ( i,j )
    按锁住帐号 account ( i )和 account(j)执行;
    A [j]:= A [j] - x ; 
    A [i]:=A [i] + x ;
    Lock-ccount.unlockaccount(i);
    Lock-account.unlockaccount(j);
    end ; 
}

  1. n个进程将字符逐个读入到一个容量为80的缓冲区中(n>1),当缓冲区满后,由输出进程Q负责一次性取走这80个字符。这种过程循环往复,请用信号量和P、V操作写出n个读入进程(P1, P2,…Pn)和输出进程Q能正确工作的的动作序列
semaphore empty = 80; // 空闲缓冲区的数量
semaphore full = 0;   // 缓冲区是否满
semaphore mutex = 1;  // 互斥信号量,保证count,int等能完整执行
int count = 0;        // 表示已写入内容的缓冲区的大小
char[80] Buffer;      // 缓冲区
int in = 0;           // 缓冲区读入游标-读入位置标志位

cobegin
process Pi(i=1,2,...,n) {
    while(true) {
        {读入一个字符到x};
        P(empty);
        P(mutex);
        Buffer[in] = x;
        in = (in + 1) % 80;
        count++;
        if(count == 80) {
            count = 0;  // 从0开始继续计数
            V(mutex);
            V(full);    // 读入满80个字符后提醒Q进程取走
        } else
        	V(mutex);
    }
}

process Q {
    while(true) {
        P(full);
        P(mutex);
        for(int j=0; j<80; j++)
        	read Buffer[j];
        in = 0;
        V(mutex);
        for(int j=0; j<80; j++)
        	V(empty);
    }
}
coend

  1. 某大型银行办理人民币储蓄业务,由n个储蓄员负责。每个顾客进入银行后先至取号机取一个号,并且在等待区找到空沙发坐下等着叫号。取号机给出的号码依次递增,并假定有足够多的空沙发容纳顾客。当一个储蓄员空闲下来,就叫下一个号。
var customer_count, server_count, mutex: semaphore;
    customer_count:=0; server_count:=n; 
    mutex:=1; 
 
process customeri(i=1,2,….)
     begin
          take a number;
          P(mutex);
          等待区找到空沙发坐下;
          V(mutex);
          V(customer_count);
          P(server_count);
     end;
 
Process servers j(j=1,2,3,…)
     Begin
      L: P(customer_count);
         P(mutex);  //涉及到叫下一个号的问题,必须保证原子性
  			被呼号顾客离开沙发走出等待区;
         V(mutex);
       		为该号客人服务;
       		客人离开;
         V(server_count);
      go to L;
     end; 
理发师问题

理发店理有一位理发师、一把理发椅和n把供等候理发的顾客坐的椅子

如果没有顾客,理发师便在理发椅上睡觉

一个顾客到来时,它必须叫醒理发师

如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开

int waiting=0;              //等候理发顾客坐的椅子数
int CHAIRS=N;               //为顾客准备的椅子数
semaphore customers, barbers, mutex;
customers=0; barbers=0; mutex=1;
 
process barber( ) {
while(true) {
  P(customers); 
    //有顾客吗?若无顾客,理发师睡眠
  P(mutex);           
    //若有顾客时,进入临界区
    waiting--;  //等候顾客数少一个
  V(barbers); //理发师准备为顾客理发
  V(mutex);          //退出临界区
  cut_hair(); 
      //理发师正在理发(非临界区)
	}
}
 
process customer_i( ) {
    P(mutex);              //进入临界区
    if(waiting<CHAIRS) {     
      //有空椅子吗
      waiting++;  //等候顾客数加1
    V(customers);  //唤醒理发师
    V(mutex);      //退出临界区
     P(barbers);  
        //理发师忙,顾客坐下等待
     get_haircut(); //否则顾客坐下理发
     }
    else  V(mutex); //人满了,走吧!
}
  1. 今有k个进程,它们的标号依次为1、2、…、k,如果允许它们同时读文件file,但必须满足条件:参加同时读文件的进程的标号之和需小于M(k<M),请使用:1)信号量与P、V操作,2)管程,编写出协调多进程读文件的程序。

    1) 使用信号量与P、V操作
    semaphore waits,mutex;
       int numbersum=0;
       wait=0;mutex=1;
    cobegin
    process readeri(int number) {    //i=1,2,…
          P(mutex);
    while(numbersum+number>=M)
         {V(mutex);P(waits);}
           numbersum=numbersum+number;
          V(mutex);
          Read file;
          P(mutex);
          numbersum=numbersum-number;
          V(waits);
          V(mutex);
    }
     
    自写:
    process readeri(int number) { //i=1,2,…
        P(mutex);
        while (numbersum + number >= M) {
            P(waits);
        }
        numbersum = numbersum + number;
        V(mutex);
        Read file;
        P(mutex);
        numbersum = numbersum - number;
        V(waits);
        V(mutex);
    }
     
    coend
    
  2. 假设一个录像厅有0,1,2三种不同的录像片可由观众选择放映。录像厅的放映规则为:
    1)任何时刻最多只能放映一种录像片,正在放映的录像片是自动循环放映的。最后一个观众主动离开时结束当前录像片的放映。
    2)选择当前正在放映录像片的观众可立即进入,允许同时有多位选择同一中录像片的观众同时观看,同时观看的观众数量不受限制。
    3)等待观看其他录像片的观众按到达顺序排队,当一种新的录像片开始放映时,所有等待观看该录像片的观众可一次进入录像厅同时观看。

    semaphore mutex=1,mutex0=1,mutex1=1,mutex2=1;
    int count0=0,count1=0,count2=0;
    
    void zero()
    {
    	P(mutex0);
    	if(count0=0) P(mutex);
    	count0++;
    	V(mutex0);
    	观影; 
    	P(mutex0);
    	count0--;
    	if(count0=0) V(mutex);
    	V(mutex0);
     } 
     
    void one()
    {
    	P(mutex1);
    	if(count1=0) P(mutex);
    	count1++;
    	V(mutex1);
    	观影; 
    	P(mutex1);
    	count1--;
    	if(count1=0) V(mutex);
    	V(mutex1);
    }
    
    void two()
    {
    	P(mutex2);
    	if(count2=0) P(mutex);
    	count2++;
    	V(mutex2);
    	观影; 
    	P(mutex2);
    	count2--;
    	if(coun2=0) V(mutex);
    	V(mutex2);
    }
    
    void main()
    {
    	cobegin
    	zero();one();two();
    	coend
    }
    
    
管程实现磁盘调度的电梯调度算法
Type diskhead = MONITOR
VAR bus:boolean;
    headpos:0..199;
	direction:(up,down);
	cylinder:Array[0..199] of condition;
	count:Array[0..199] of integer;
Define require, release;

Procedure require(dest:0..199)
Being
    If busy Then
	Begin
	   count[dest]:=count[dest] + 1;
	   wait(cylinder[dest]);
	End
	busy:=true;
	If dest < headpos Then
		direction:=down;
	Else
	If dest > headpos Then
		direction:=up;
	headpos:=dest
End;

Procedure upscan;
Var I:0..200;
    flag:(false,true);
Begin
    I:=headpos;
	flag:=false;
	While (I <= 199) and (count[I] = 0) Do
		I:=I + 1;
	If I<=199 Then
	Begin
		count[I]:=count[I] - 1;
		signal(cylinder[I]);
		flag:=true;
	End
End;

Procedure downscan;
Var I:-1..199
    flag:(false, true);
Begin
    I:=headpos;
    flag:=false;
	While (I >= 0) and (count[I] = 0) Do
		I:=I - 1;
	if I >= 0 Then
	Begin
		count[I]:=count[I] - 1;
		signal(cylinder[I]);
		flag:=true;
	End
End;

Procedure release;
Begin
	busy:=false;
	If direction = up Then
	Begin
		upscan;
		If (!flag) Then
			downscan;
	End
	Else
	Begin
		downscan;
		If (!flag) Then
			upscan;
	End
End;

Procedure initialize;
Var I:0..199;
Begin
	busy:=false;
	headpos:=0;
	direction:=up;
	For I:=0 To 199 Do
		count[I]:=0
End

Begin initialize End;

飞机票问题
Var A : ARRAY[1..m] of integer;
mutex : semaphore;
mutex:= 1;
cobegin
process Pi
	var Xi:integer;
begin
	  按旅客定票要求找到A[j];
	  P(mutex);
	  Xi := A[j];
	  if Xi>=1  then 
      begin 
        Xi:=Xi-1;A[j]:=Xi; 
        V(mutex);  {输出一张票};
      end;
	  else begin 
        V(mutex);  {输出“票已售完”};     
      end;
    goto L1;
 end;
coend
独木桥问题

详见 独木桥问题

其他课后习题

操作系统教程课后习题

`


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值