PV操作(操作系统) 详解 消费者 生产者问题

在讲解PV操作之前,需要先明白PV操作用来解决什么问题?

PV操作用以解决进程间的互斥问题

eg:火车售票问题 。以下就会出现BUG,假设当 x = 1时,如果
p1 , p2 , 同时执行,那么相当于票数为1的这张票售卖两次,这显然是不能出现的错误。

cobegin     // 表示p1 , p2 同时执行
int x = 7 ; // 假设 x 为北京到上海的机票,还剩下7张
void p1(){
    if(x>0) x = x - 1 ; cout << "买票成功" << endl ;
    else                cout << "票已售完" << endl ; 
}
void p2(){
    if(x>0) x = x - 1 ; cout << "买票成功" << endl ;
    else                cout << "票已售完" << endl ; 
}
coend 

那么如何解决???

其实很简单,只需要让p1执行的时候,p2不要执行。p2执行的时候,p1不要执行。此时就需要对该程序PV操作。参考代码如下:

Semapohore s = 1 ;    // s 为信号量,用于实现互斥操作。也是对临界资源的设定。
int x = 7 ;            // 假设 x 为北京到上海的机票,还剩下7张
cobegin               // 表示p1 , p2 同时执行
void p1(){
    p(s) ;             // 把信号量s锁住,让p2不能执行,s -- ;如果s <= 0 , 则进入等待无法向下继续执行
    if(x>0) x = x - 1 ; cout << "买票成功" << endl ;
    else                cout << "票已售完" << endl ; 
    v(s) ;   // 把信号量s锁住,让p1可以执行,s ++ 
}
void p2(){
    p(s) ;
    if(x>0) x = x - 1 ; cout << "买票成功" << endl ;
    else                cout << "票已售完" << endl ; 
    v(s) ;
}
coend 

经典进程问题:生产者 消费者问题

1:一个生产者与一个消费者共同使用一个缓冲区 且只能放进一件产品

Semaphore s = 1 ;  // 代表缓冲区能否放进产品
Semaphore t = 0 ;  // 代表缓冲区能否取出产品
cobegin 
void prudece(){
     p(s) ;       // 把缓冲区锁住,无法放进产品
     生产产品并且放进缓冲区
     v(t) ;        // 缓冲区中可以取出产品
}
void consumer(){
     p(t) ; 
     从缓冲区取出产品
     v(s) ;  // 释放缓冲区。
}

2:一个生产者与一个消费者共同使用一个缓冲区 且能放进n件产品(n>1);
(与第一个不同的是,缓冲区中不止一件产品)

Semaphore s = 1 ;  // 代表缓冲区能否放进产品 , s = 1 表示能放进
Semaphore t = 0 ;  // 代表缓冲区能否取出产品 , t = 0 表示无法取出
int b[n] ;         // 缓冲区的每一个位置是否有产品存放
int w1 = 0 , w2 = 0 ; // 代表产品以及存放到的位置 和 产品应该要取出来的位置。  
cobegin 
void prudece(){
     p(s) ;       // 把缓冲区锁住,无法放进产品
     生产产品并且放进缓冲区
     b[w1] = 1 ; // 表示 w1 这个位置  已经放进产品
     w1 = (w1 + 1) % n ; // 下次放进产品则需要在下一个位置
     v(t) ;        // 缓冲区中可以取出产品
}
void consumer(){
     p(t) ; 
     从缓冲区w2取出产品
     w2 = (w2 + 1) % n ; 
     v(s) ;  // 释放缓冲区。
}

3:多个生产者与多个消费者共同使用一个缓冲区 且能放进n件产品(n>1);(与第二个不同的是,有多个生产者可以共同生产,但是不能同时放进缓冲区;有多个消费者可以共同消费,但是不能同时从缓冲区取出产品)

思路:

1 :  设置三个信号量 。
   (1):s = 1 , 表示缓冲区可以使用
    (2) :  empty = n , 表示缓冲区中空的数量(即表示可以放进产品的数量)
    (3) :  full = 0 ;  表示缓冲区已经放进产品的数量    
2 :  设置 w1 , w2 两个值,分别表示从缓冲区w1值放进产品 , 从缓冲区w2值取出产品

3 : s 作为互斥信号使用 

代码如下:

Semaphore s = 1 , empty = n , full = 0 ;
int w1 = 0 , w2 = 0 ;
int b[n] ;
cobegin
void pruduct(){
     p(s) ;
     p(empty) ;
     b[w1] = 1 ;  // 在w1放进产品 , 用1表示(注:只是为了表示简单)
     w1 = (w1 + 1) % n ;
     v(s) ;
     v(full) ;
}
void consume(){
     p(s) ;
     p(full) ;
     b[w2] = 0 ;
     w2 = (w2 + 1) % n ;
     v(s) ; 
     v(empty) ;
}
  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值