回 帖 发 新 帖 刷新版面

主题:[原创]求教关于 操作系统 PV原语的问题!!!!!

求教一个关于利用PV 原语操作实现进程间的互斥的问题:
  设生产围棋的工人不小心把黑子和白子都装入到一个箱子中,现在要利用自动分拣系统把黑子和白子区分: 
  1)进程A专门拣黑子 ,进程B专门拣白子;
  2)每个进程每次只拣一个子,当一个进程拣子时令一个进程不允许拣子;
  分析:
      1> 确定进程间的关系 由功能2可知进程之间是互斥的关系.
      2> 确定信号量及其值.由于进程A,B 要互斥进入箱子去拣子,箱子就是二个进程公用的资源.所以设置信号量S,其值取决于公有资源的数目,由于箱子只有一个s的初值应设置为1;

    实现:
  begin:
       s:sem;
       s:1;
    cobegin:
       process A:
        begin
         L1: P(s);
            拣黑子;
            V(s);
              go to L1;
        end;
 
      cobegin:
      process B:
        begin
         L2: P(s);
             拣白子;
             V(s);
              go to L2;
        end;
    coend
  end;

PV 互斥:我自己的理解是: P(s) 占用资源: s--; then s>=0 进程继续 else 等待状态或进程调度
                        V(s) 释放资源: v++; then s>0 进程继续 else 唤醒或转进程调度
 
我不理解的就是: 
                1. p(s) v(s) 是不是一个 各自独立的循环 例如 s=2时 1>s--;(s=1)>=0;进程继续 再然后就是循环:..... 2>s--; (s=-1)>=0; 进程等待; 还是在1>的时候执行V(s) ?
                2. 上面那个围棋的例子 是不是等到A 全部完成了(把黑子都拣完了) B 再继续....(请详细解释)
                3. 能不能用更具体点的自然语言 把上面那个围棋的例子 详细的描述一下; 

结语:
      我对PV这个概念琢磨了一个下午了! 可是越想就越郁闷!! 
      我是学Java的 由于近期参加专升本考试。。。。如果上面的问题太低等的话请不要骂我呀!! 现在压力很大了已经!! 别在伤俺自尊咯!

回复列表 (共5个回复)

沙发

o 我晕!! 为啥都不理我呢!!!

板凳

2. 上面那个围棋的例子 是不是等到A 全部完成了(把黑子都拣完了) B 再继续.

    如果等到A 全部完成了B 再继续,那不是顺序执行吗? 那里有并行的概念。

3 楼

2楼的. PV原语本身好象就是描述 进程之间顺序执行吧. 
如果2个进程一起执行. 用到临界区的资源的话.. 那起不是乱套拉吗? 

  新人. 这么理解的..  我感觉应该是把A 全部完成在继续 B

4 楼

实现应该是正确的吧~ 
欧也是新人` 说说自己的想法`
假如A最先获得CPU的资源 先执行了`那么P操作之后,V操作之前,B就要等待,
 如果在A进程 P V之间 失去了CPU资源(被时钟中断或者别的中断 打断)之后进入等待队列,此时B进程依然无法执行。
 如果在A进程 P之前(假设有其他代码),V之后,丧失了CPU资源`此时B就有获得CPU资源的机会了` 所以还是有可能 执行的。
说的多任务操作系统阿``哈哈`

5 楼

先给出我的解法。

int numOfBox = 1;               //箱子数目
int numOfBlack = N1;            //黑子数目
int numOfWhite = N2;            //白子数目

void process_A(void)
{
        while (true)
        {
                P(numOfBox);  
                
                pick_black_mov();       //拣黑子

                V(numOfBox);
                
                if ((--numOfBlack) == 0)  //黑棋子拣完了,就退出
                        break;
        }              

                
}

void process_B(void)
{
        while (true)
        {
                P(numOfBox);

                pick_white_mov();       //拣白子

                V(numOfBox);

                if ((--numOfWhite) == 0) //白棋子拣完了,就退出
                        break;
        }                
}        


PV 原语可以用来描述资源的竞争和合作。当中的资源是广义的,你要完成某一件事情,需要的东西就可以叫做资源。比如,你要打印,那打印机就是资源,你要过马路,那个路口就是资源。

其中P原语就可以想象成一个申请资源的动作(或者理解成用掉资源),要是申请到,就将资源减少1,跟着就可以离开了; 要是资源没有了,也将资源数目减少1(为什么还是要减1呢?是为了描述一种欠帐,之后资源来了就不用再减1了)跟着等待,这可以想象成一种预定的动作。所以P原语可以理解成,有则申请,没有则预定并等待。

V原语可以理解成一种资源的释放(或者理解成增加资源)。先将资源数目加1,如果之前有人等待着,就将它唤醒。相当于之前有人预定了,就将资源给他,他就可以离开,不用再等待了。(因为之前已经事先将资源数目减1了,这里就不用再减了)

P,V操作的对象就是资源。它的初值就是资源的最初数量。

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
分析那个黑白棋子的问题。

对于进程A来说,要实现到拣黑子到里面这事情,需要黑棋子、和箱子。这样黑棋子和箱子对于进程A来说,就是资源。不过黑棋子是自己独占的,所以这个资源总是能满足,就不用考虑。另外箱子是和进程B共用的,B用了A就不能够用,这个箱子资源就用考虑了。如果问题变了,变成黑棋子不是独占的,这样问题就用重新分析了。

同样对于进程B来说,白棋子和箱子也是它的资源。其中白棋子不用考虑,就只需要考虑箱子。

分析需要用到什么资源,考虑和别人共同分享的资源。资源已经不用了,就释放掉,不要占着,影响别人。

箱子数目为最初数目为1。

进程A, 先占着箱子,跟着拣黑子,跟着释放掉箱子。
进程B, 先占着箱子,跟着拣白子,跟着释放掉箱子。

检验这个算法对不对的时候,有点要注意,除了原语之外,任何地方都可以被打断。这个算法不是等到A拣完,B才会拣。你可以想象成两个人,A正在捡的时候,B随时会来(B来不来,不能确定), 要是B来了,B就等着,等A拣完,B就占着箱子继续捡。考虑这些并行问题的时候,不能够就考虑某一个进程,要所有的情况一起考虑。所以这些多线程,多进程的程序最难调式了,一不小心,就会出错。

你可以想象成你是一个管理者,将各个进程想象成各个人,你去制定一些方案去管理这些人。要是你这个方案可行,你的程序就是对的。

我来回复

您尚未登录,请登录后再回复。点此登录或注册