操作系统复习笔记(二)
1.问答题:有一个文件F,有A,B两组进程共享这个文件,同组的进程可以同时读文件F,但当有A组(或B组)的进程在读文件F时就不允许B组(或A组)的进程读,
解:定义两个计数器C1,C2,分别记录A组和B组中读文件的进程数,三个信号量S1,S2,SAB,其中S1用于通知A组进程已经有B组进程在读文件F了,S2用于通知B进程已经有A进程在读文件F了,SAB用于实现对共享变量C1和C2以及临界区的互斥访问.
 begin
begin var S1,S2,SAB:semaphore = 1,1,1;
            var S1,S2,SAB:semaphore = 1,1,1; C1,C2:integer = 0,0;
                 C1,C2:integer = 0,0;
 process A-i(i=1,2
                   process A-i(i=1,2 )
) begin
                    begin repeat
                       repeat P(SAB);
             P(SAB); C1 = C1+1;
                   C1 = C1+1; if(C1=1) then P(S2);
             if(C1=1) then P(S2); V(SAB);
             V(SAB); 读文件F;
              读文件F; P(SAB)
             P(SAB) C1 = C1-1;
             C1 = C1-1; if(C1==0)V(S2)
             if(C1==0)V(S2) V(SAB)
             V(SAB)   until false
                until false end
                    end       
    
 process B-i(i=1,2
                   process B-i(i=1,2 )
) begin
                    begin repeat
                       repeat P(SAB);
             P(SAB); C2 = C2+1;
                   C2 = C2+1; if(C2=1) then P(S1);
             if(C2=1) then P(S1); V(SAB);
             V(SAB); 读文件F;
              读文件F; P(SAB)
             P(SAB) C2 = C2-1;
             C2 = C2-1; if(C2==0)V(S1)
             if(C2==0)V(S1) V(SAB)
             V(SAB)   until false
                until false end
                    end         end
  end 
2,应用题:get进程读数据到buffer1里,然后进程copy从buffer1里的数据复制到buffer2里,再由put进程取出buffer2里的数据去进行打印.
分析:这是两个阶段的生产-消费问题.第一阶段的生产者和消费者是get和copy,第二阶段的生产者和消费者是copy和put.为简单计,假设buffer1,buffer2 都是单缓冲区,因此只要设4个信号量empty1,full1,empty2,full2,就可以了.
 begin
 begin  buffer:integer
              buffer:integer empty1,empty2,full1,full2,:semaphore=1,1,0,0;
              empty1,empty2,full1,full2,:semaphore=1,1,0,0; cobegin
              cobegin
 process Get
                        process Get begin
                            begin repeat
                               repeat 读数据
                  读数据 p(empty1);
                                p(empty1); 把数据放到buffer1里
                                把数据放到buffer1里 v(full1);
                                 v(full1); until false
                                 until false end
                            end
 process Copy
                        process Copy begin
                            begin repeat
                  repeat p(full1)
                                p(full1) 从buffer1里读出数据
                                从buffer1里读出数据 v(empty1);
                                v(empty1); p(empty2)
                  p(empty2) 把数据放到buffer2里
                                把数据放到buffer2里 v(full2)
                  v(full2) until false
                                 until false end
                           end
 process Put
         process Put begin
                            begin repeat
                  repeat p(empty2)
                                p(empty2) 从buffer2里读出数据
                                从buffer2里读出数据 v(full2);
                                v(full2);          打印数据
                                打印数据 until false
                                 until false end
                           end coend
              coend end
  end3.输入进程输入数据到缓冲区buffer1中,计算进程从buffer1中读出数据进行计算,并把结果送入buffer2,然后打印进程从buffer2中读出结果进行打印.假设缓冲区大小分别为n1和n2.
 begin
 begin  buffer:integer
              buffer:integer empty1,empty2,full1,full2,mutex1,mutex2:semaphore=n1,n2,0,0,1,1;
              empty1,empty2,full1,full2,mutex1,mutex2:semaphore=n1,n2,0,0,1,1; cobegin
              cobegin
 process Input
                        process Input begin
                            begin repeat
                               repeat 输入数据
                  输入数据 p(empty1);
                                p(empty1); p(mutex1);
                  p(mutex1); 把数据放到buffer1里
                                把数据放到buffer1里 v(mutex1);
                  v(mutex1); v(full1);
                                 v(full1); until false
                                 until false end
                            end
 process Compute
                        process Compute begin
                            begin repeat
                  repeat p(full1)
                                p(full1) p(mutex1);
                  p(mutex1); 从buffer1里读出数据
                                从buffer1里读出数据 v(mutex1);
                                v(mutex1); v(empty1);
                                v(empty1);
 p(empty2)
                  p(empty2) p(mutex2);
                  p(mutex2); 把数据放到buffer2里
                                把数据放到buffer2里 v(mutex2);
                   v(mutex2); v(full2);
                  v(full2); until false
                                 until false end
                           end
 process Print
         process Print begin
                            begin repeat
                  repeat p(empty2)
                                p(empty2) p(mutex2);
                   p(mutex2); 从buffer2里读出数据
                                从buffer2里读出数据 v(full2);
                  v(full2); v(full2);
                                v(full2);          打印数据
                                打印数据 until false
                                 until false end
                           end coend
              coend end
  end4.过桥问题.
(1)桥每次只能有一辆车通过,
(2)不允许两车交会,但允许同方向的多辆车依次通过
解:(1)
 begin
    begin    mutex:semaphore=1;
                     mutex:semaphore=1; cobegin
                     cobegin process Scar//南边来的车
                        process Scar//南边来的车 begin
                            begin come;
                                come; p(mutex);
                                p(mutex); 过桥;
                                过桥; v(mutex);
                                 v(mutex); go;
                                go; end
                            end
 process Ncar//北边来的车
                        process Ncar//北边来的车 begin
                            begin come;
                 come; p(mutex);
                                p(mutex); 过桥;
                                过桥; v(mutex);
                                 v(mutex); go;
                                go; end
                           end coend
                coend end
     end(2)
 begi
 begi var Smutex=1,Nmutex=1,mutex=1:semaphore;
         var Smutex=1,Nmutex=1,mutex=1:semaphore; SCarCount=0,NCarCount=0:integer;
    SCarCount=0,NCarCount=0:integer; cobegin
                cobegin process Scari(i=1,2
                    process Scari(i=1,2 )
) begin
                    begin p(Smutex);
                        p(Smutex);  if(SCarCount=0) then p(mutex);
                         if(SCarCount=0) then p(mutex); SCarCount = SCarCount +1;
           SCarCount = SCarCount +1; v(Smutex);
                        v(Smutex);  过桥;
          过桥; p(Smutex);
           p(Smutex);  SCarCount = SCarCount -1;
           SCarCount = SCarCount -1; if(SCarCount=0) then v(mutex);
            if(SCarCount=0) then v(mutex); v(Smutex);
                        v(Smutex);  end
                    end
 process Ncarj(j=1,2
                process Ncarj(j=1,2 )
) begin
                    begin p(Nmutex);
                        p(Nmutex);  if(NCarCount=0) then p(mutex);
                         if(NCarCount=0) then p(mutex); NCarCount = NCarCount +1;
          NCarCount = NCarCount +1; v(Nmutex);
                        v(Nmutex);  过桥;
          过桥; p(Nmutex);
           p(Nmutex);  NCarCount = NCarCount -1;
          NCarCount = NCarCount -1; if(NCarCount=0) then v(mutex);
            if(NCarCount=0) then v(mutex); v(Nmutex);
                        v(Nmutex);  end
                    end coend
                coend end
end
5.在管道通信机制中,用信号量描述读进程和写进程访问管道文件的过程,假设管道文件大小为10KB.
分析:在UNIX系统中,利用一个打开的共享文件来连接两个相互通信的进程,这个共享文件叫管道.作为管道输入的发送进程,以字符流的形式将信息送入管道,而作为管道输出的接收进程,从管道中获取信息.管道通信机制要提供三方面的协调能力:(1)互斥.当一个进程对管道进行读/写操作时,另一个进程必须等待.(2) 同步.当写进程把数据写入管道后便去睡眠等待,直到输出进程取走数据后唤醒它.若一次写入的数据超过缓冲区剩余空间的大小,当缓冲区满时,写进程必须阻塞,并唤醒读进程。(3)对方是否存在.只有确定对方存在时,才能够进行通信.
本题只需要考虑互斥,同步问题。由于只有一对进程访问管道,因此不需要设置互斥信号量,只要设置两个同步信号量empty,full.分别表示管道可写和可读.
 begin
 begin  pipe:array[0
                  pipe:array[0 9] of kilobytes;
9] of kilobytes; ts=10,length,in=0,out=0:integer;
     ts=10,length,in=0,out=0:integer; empty,full:semaphore=1,0;
                   empty,full:semaphore=1,0; cobegin
                    cobegin process PipeWriter
                        process PipeWriter begin
                            begin repeat
                               repeat 产生数据;
        产生数据; p(empty);
                                p(empty); length = data length;
                        length = data length; while(length>0 and ts>0)
         while(length>0 and ts>0) begin
        begin pipe[in] = data of 1KB;
             pipe[in] = data of 1KB; in = (in+1) mod n;
             in = (in+1) mod n; ts = ts-1;
             ts = ts-1; length = length - 1;
             length = length - 1; end
        end v(full);
                                 v(full); end
                            end process Consumer
                        process Consumer begin
                            begin repeat;
                  repeat; p(full);
                                p(full); 从缓冲区取出一件物品;
                                从缓冲区取出一件物品; out = (out+1) mod n;
        out = (out+1) mod n; ts = ts +1;
        ts = ts +1; v(empty);
                                v(empty); end
                           end coend
               coend end
    end作者:洞庭散人
出处:http://phinecos.cnblogs.com/
本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。
posted on 2006-08-25 21:48 Phinecos(洞庭散人) 阅读(1136) 评论(0) 收藏 举报
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号