信号量PV操作

基本介绍

  • 信号量(Semaphore):是表示资源的实体,是一个与队列有关的整型变量,其值仅能由P、V操作改变。
  • 信号量分为:公用信号量和私用信号量。
  • 公用信号量:用于实现进程间的互斥,初值通常设为1,它所联系的一组并发进程均可对它实施P、V操作;
  • 私用信号量:用于实现进程间的同步,初始值通常设为0或n,允许拥有它的进程对其实施Р操作。

数据结构

信号量的数据结构:

struct semaphore{
int value; //系统中的资源数
pointer_PCB queue; //阻塞进程队列
};//PCB表示进程控制块
//声明
semaphore s;

PV操作

P(s){//申请资源
if(--s.value<0){
该进程设置为阻塞态
将该进程的PCB插入阻塞队列s.queue末尾
}
}
V(s){//释放资源
if(++s.value <= 0){
唤醒相应阻塞队列s.queue中等待的一个进程
改变其状态为就绪态
并将其插入就绪队列
}
}

s. value >= 0时,其值表示还有可用的资源数;

s. value < 0时,其绝对值表示有多少个进程因申请该信号量表示的资源,得不到而进入阻塞态;

解决进程互斥问题

把P1-P3进程的互斥操作包括在一个PV操作对中

由P2进入

举例1:

启发:写并发进程的时候需要明确互斥区

  1. 不同进程未进入互斥区时可以并发
  2. 不同进程进入互斥区时要用PV操作控制

解决进程同步问题

在同步问题中信号量的value值相比于“资源”资源来说,理解为“权限”会更合适,在一个同步问题中,一个进程的执行权限是由它的前驱进程赋予的

代码实现(以同步问题为例)

为了便于实现,将程序的运行操作也封装到PV操作中,即

  • 如果P操作为信号量申请到权限,那么直接执行信号量所对应的进程
  • 如果V操作赋予了信号量权限且信号量的阻塞队列中有进程,那么直接执行阻塞队列中的进程

代码如下:【本人才疏学浅,如有不足恳请斧正】

#include<iostream>
#include<string>
#include<queue>
using namespace std;
/*定义类:process表示一个进程*/
class process{
public :
/*构造函数*/
process() = default;
process(const string &name) : process_name(name){}
process(const process &p) :
process_name(p.process_name){}
/*成员函数*/
//执行进程
void _on(){cout<<process_name+": on"<<endl;}
//关闭进程
void _off() {cout<<process_name+": of"<<endl;}
//进程名
string process_name;
}; /*定义类:semaphore表示信号量*/
/*一个信号量控制一个进程*/
class semaphore{
/*友元声明:确保PV操作可以访问semaphore私有成员*/
friend void P(semaphore &s);
friend void V(semaphore &s);
public:
/*构造函数:参数为信号量控制的进程*/
semaphore(const process &p) :
present(p){};
private :
int value = 0; //同步问题value初始化为0
process present; //该信号量控制的进程
queue<process> blocked_processes; //阻塞队列
}; /*P操作:申请资源(权限)*/
void P(semaphore &s){
--s.value;//申请
if(s.value<0){//无资源(权限):进程进入阻塞队列
//打印提示信息
cout<<s.present.process_name+" is blocked"<<endl;
//将进程加入阻塞队列
s.blocked_processes.push(s.present);
}
else{//有资源:直接执行
s.present._on();
}
}
/*V操作:返回资源(给予权限)*/
void V(semaphore &s){
++s.value;//赋予
if(s.value>=0){//如果阻塞队列有进程:唤醒阻塞进程
if(!s.blocked_processes.empty()){
s.blocked_processes.front()._on();
s.blocked_processes.pop();
}
}
//否则什么也不做
}
//开车进程
process speed_up("speed_up");
//开门进程
process open_door("open_door");
//用两个信号量分别控制开车进程和开门进程
semaphore OpenDoor(open_door), Speed_Up(speed_up); int main(){
V(OpenDoor); //赋予开车门的权限
P(OpenDoor); //申请权限:有权限,可以开,打印open_door: on
P(OpenDoor); //申请权限:无权限,开不了门,进入开门阻塞队列
P(Speed_Up); //申请权限:无权限,开不了车,进入开车阻塞队列
V(Speed_Up); //赋予权限:执行开车阻塞队列进程,打印speed_up: on
V(OpenDoor); //赋予权限:执行开门阻塞队列进程,打印open_door: on
return 0;
}

运行结果:

进程相互作用之信号量PV操作及其代码实现的更多相关文章

  1. Linux下IPC中的信号量PV操作

    代码如下所示,两边对照查看程序!(左图为先运行进程 右图为后运行进程)    运行的效果就是:当左边的进程检测到EOF,释放资源V操作之后,右边的进程会迅速的执行对应的printf的操作! 所有代码文 ...

  2. linux下的信号量PV操作进阶之路

    一.同步和互斥机制 信号量 互斥锁 同步:指多个任务按照约定的先后次序相互配合来完成一件事情. 比如读线程等待写线程写完之后再去读. 二.信号量-P/V操作 P(s)含义: if(信号量>0) ...

  3. java信号量PV操作 解决生产者-消费者问题

    package test1; /** * 该例子演示生产者和消费者的问题(设只有一个缓存空间.一个消费者和一个生产者) * MySystem类定义了缓冲区个数以及信号量 * @author HYY * ...

  4. Operating System-进程/线程内部通信-信号量和PV操作

    本文介绍操作系统进程管理的两个核心概念: 信号量 PV操作 一.信号量介绍 1.1 信号量引入 信号量(Semaphore)1965年由Dijkstra引入的.信号量一般由一个值是一个变量,其值有可能 ...

  5. 信号量与PV操作

    在计算机操作系统中,PV操作是进程管理中的难点.首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:    P(S):①将信号量S的 ...

  6. Pintos修改优先级捐赠、嵌套捐赠、锁的获得与释放、信号量及PV操作

    Pintos修改优先级捐赠.嵌套捐赠.锁的获得与释放.信号量及PV操作 原有的优先级更改的情况下面没有考虑到捐赠的情况,仅仅只是改变更改了当前线程的优先级,更别说恢复原本优先级了,所以不能通过任何有关 ...

  7. 信号量和PV操作写出Bakery算法的同步程序

    面包店烹制面包及蛋糕,由n个销售员卖出.当有顾客进店购买面包或蛋糕时,应先在取号机上取号,然后等待叫号,若有销售员空闲时便叫下一号,试用信号量和PV操作写出Bakery算法的同步程序. 设计要求 1) ...

  8. 转 信号量与PV操作

    在计算机操作系统中,PV操作是进程管理中的难点.首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:    P(S):①将信号量S的 ...

  9. 【转】进程同步之信号量机制(pv操作)及三个经典同步问题

    原文地址:http://blog.csdn.net/speedme/article/details/17597373 上篇博客中(进程同步之临界区域问题及Peterson算法),我们对临界区,临界资源 ...

  10. OS__信号量(semaphore)PV操作

    信号量的概念 1.信号量的类型定义 信号量(semaphore)的数据结构为记录型数据结构一个值和一个指针,指针指向等待该信号量的下一个进程.信号量的值与相应资源的使用情况有关,在操作系统中,信号量用 ...

随机推荐

  1. 【CMake系列】01-CMake是什么

    在很多开源项目中,经常可以看到CMakeLists.txt 这一文件,依靠它才能完成项目的配置运行过程.那它是什么? 接下来,在这个专栏中,我们将系统学习CMake这一个重要工具. 本专栏的实践代码全 ...

  2. cdh6.3.2 hue集成hbase

    参考地址:https://blog.csdn.net/u010886217/article/details/98606976

  3. win10自动更新导致的任务栏假死,右键单击任务栏延迟菜单延迟出现

    系统是win10企业版,前天晚上回家之前,电脑还是好好的,然后前天早上跑过来以后,发现电脑自动重启了,我还以为是办公室停电了之类的(现在想了一下愚蠢,停电不会自动开机),没想到是自动更新 然后我发现, ...

  4. 【YashanDB知识库】outline固化执行计划

    [问题分类]性能优化,功能使用 [关键字]outline [问题描述]防止SQL执行计划突变,用outline固化执行计划 [问题原因分析]防止SQL执行计划突变,用outline固化执行计划 [解决 ...

  5. [Udemy] AWS Certified Data Analytics Specialty - 5.Visualization

    QuickSight SPICE是 QuickSight 的加速技术

  6. 线性dp:LeetCode516 .最长回文子序列

    LeetCode516 .最长回文子序列 题目叙述: 力扣题目链接(opens new window) 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度. 子序列定义为:不改变剩余字 ...

  7. TypeScript 5.1 & 5.2

    getter 和 setter 可以完全不同类型了 以前我们提过,getter 的类型至少要是其中一个 setter 的类型.这个限制被突破了.现在可以完全使用不同类型了. v5.1 后,没有再报错了 ...

  8. JavaScript – 理解 Function, Object, Prototype, This, Class, Mixins

    前言 JavaScript (简称 JS) 有几个概念 Object, Prototype, This, Function, Class 是比较难理解的 (相对其它语言 C# / Java 而已),这 ...

  9. C语言位域的内存布局

    本文将先粗略介绍大小端,和大小端的测试方法,最后介绍位域的内存布局. 1. 大小端 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中. 小端模式,是指数据的高字节保存 ...

  10. [OI] 数学与推论证明 3(高中数学篇)

    1 \[\color{#40865d}(2) \] \(f(x)=x^{2}-a(x+a\ln x)(a\neq0)\),若 \(f(1)+f'(1)=0\) 且 \(a\gt 0\),问可以得到什么 ...