操作系统-PV操作的原理和几种常见问题

本文探讨了操作系统中PV操作的基本原理,并通过分析机票问题、生产者消费者问题、哲学家就餐问题、写者问题、男女共浴问题、汽车过桥问题以及理发师问题,阐述了PV操作在解决同步和互斥问题中的关键作用。
摘要由CSDN通过智能技术生成
信号量是一种变量类型,用一个记录型数据结构表示,有两个分量:信号量的值和信号量队列指针
除了赋初值外,信号量仅能通过同步原语PV对其进行操作
s.value为正时,此值为封锁进程前对s信号量可施行的P操作数,即s代表实际可用的物理资源
s.value为负时,其绝对值为对信号量s实施P操作而被封锁并进入信号量s等待队列的进程数,即登记排列在s信号量队列之中等待的进程个数
s.value为0时,无资源且无进程等待
信号量按其取值可分为二值信号量和一般信号量(计数信号量),记录型信号量和PV操作定义为如下数据结构和不可中断过程:
typedef struct semaphore { 
    int value;
    struct pcb *list; //信号量队列指针
}
void P(semaphore s){
    s.value--;
    if(s.value<0) sleep(s.list); //若信号量值小于0,执行P操作的进程调用sleep(s.list)阻塞自己,被置成等待信号量s状态并移入s信号量队列,转向进程调度程序
}
void V(semaphore s){
    s.value++;
    if(s.value<=0) wakeup(s.list); //若信号量小于等于0,则调用wakeup(s.list)从信号量s队列中释放一个等待信号量s的进程并转换成就绪态,进程则继续运行
}
二值信号量虽然仅能取值0、1,但它和其它记录型信号量有一样的表达能力
  • 机票问题
注意:(1)P操作与V操作在执行路径上必须一一对应,有一个P操作就有一个V操作;(2)输出一张票的操作不应放在临界区内
int A[m];
Semaphore s = 1;
cobegin
process Pi {
    int Xi;
    Li:按旅客定票要求找到A[j];
    P(s);
    Xi = A[j];
    If (Xi>=1) { Xi=Xi-1; A[j]=Xi;V(s); 输出一张票;} 
    else {V(s); 输出票已售完;}   
    goto Li;
    }
coend;
只有相同航班的票数才是相关的临界资源,所以用一个信号量s处理全部机票会影响进程并发度
可以让每一个航班都有自己的临界区,把信号量改为s[m]
int A[m];
Semaphore s[m];    //每一个航班都有自己的临界区
For (int j=0;j<m;i++) s[j] = 1;
cobegin
process Pi {
    int Xi;
    L1:按旅客定票要求找到A[j];
    P(s[j]);
    Xi = A[j];
    If (Xi>=1) { Xi=Xi-1; A[j]=Xi;V(s[j]); 输出一张票;
    } else {V(s[j]); 输出票已售完;}
    goto L1;
    }
coend;
  • 生产者消费者问题
(1)1生产者1消费者1缓冲区问题
int
  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值