进程相互作用之信号量PV操作及其代码实现
信号量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:


启发:写并发进程的时候需要明确互斥区
- 不同进程未进入互斥区时可以并发
- 不同进程进入互斥区时要用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操作及其代码实现的更多相关文章
- Linux下IPC中的信号量PV操作
代码如下所示,两边对照查看程序!(左图为先运行进程 右图为后运行进程) 运行的效果就是:当左边的进程检测到EOF,释放资源V操作之后,右边的进程会迅速的执行对应的printf的操作! 所有代码文 ...
- linux下的信号量PV操作进阶之路
一.同步和互斥机制 信号量 互斥锁 同步:指多个任务按照约定的先后次序相互配合来完成一件事情. 比如读线程等待写线程写完之后再去读. 二.信号量-P/V操作 P(s)含义: if(信号量>0) ...
- java信号量PV操作 解决生产者-消费者问题
package test1; /** * 该例子演示生产者和消费者的问题(设只有一个缓存空间.一个消费者和一个生产者) * MySystem类定义了缓冲区个数以及信号量 * @author HYY * ...
- Operating System-进程/线程内部通信-信号量和PV操作
本文介绍操作系统进程管理的两个核心概念: 信号量 PV操作 一.信号量介绍 1.1 信号量引入 信号量(Semaphore)1965年由Dijkstra引入的.信号量一般由一个值是一个变量,其值有可能 ...
- 信号量与PV操作
在计算机操作系统中,PV操作是进程管理中的难点.首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的 ...
- Pintos修改优先级捐赠、嵌套捐赠、锁的获得与释放、信号量及PV操作
Pintos修改优先级捐赠.嵌套捐赠.锁的获得与释放.信号量及PV操作 原有的优先级更改的情况下面没有考虑到捐赠的情况,仅仅只是改变更改了当前线程的优先级,更别说恢复原本优先级了,所以不能通过任何有关 ...
- 信号量和PV操作写出Bakery算法的同步程序
面包店烹制面包及蛋糕,由n个销售员卖出.当有顾客进店购买面包或蛋糕时,应先在取号机上取号,然后等待叫号,若有销售员空闲时便叫下一号,试用信号量和PV操作写出Bakery算法的同步程序. 设计要求 1) ...
- 转 信号量与PV操作
在计算机操作系统中,PV操作是进程管理中的难点.首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的 ...
- 【转】进程同步之信号量机制(pv操作)及三个经典同步问题
原文地址:http://blog.csdn.net/speedme/article/details/17597373 上篇博客中(进程同步之临界区域问题及Peterson算法),我们对临界区,临界资源 ...
- OS__信号量(semaphore)PV操作
信号量的概念 1.信号量的类型定义 信号量(semaphore)的数据结构为记录型数据结构一个值和一个指针,指针指向等待该信号量的下一个进程.信号量的值与相应资源的使用情况有关,在操作系统中,信号量用 ...
随机推荐
- OpenTelemetry 实战:从零实现应用指标监控
前言 在上一篇文章:OpenTelemetry 实战:从零实现分布式链路追踪讲解了链路相关的实战,本次我们继续跟进如何使用 OpenTelemetry 集成 metrics 监控. 建议对指标监控不太 ...
- 【Python后端开发】Flask之ORM数据库操作
一.前言 ORM 对象映射关系程序. 通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直 ...
- windows 误删除\AppData\Local\文件夹后 异常的修复
背景:清除Temp文件夹时,路径复制错误,少复制了Temp,导致删除了文件夹 C:\Users\username\AppData\Local\ 异常现象: 估计删除Local文件夹后,出现的问题应该会 ...
- maven 网关应用:[NACOS ConnectException httpPost] currentServerAddr: http://localhost:8848,
网关应用运行忽然报错:[NACOS ConnectException httpPost] currentServerAddr: http://localhost:8848, 虽然调整了代码逻辑,但是n ...
- 【YashanDB知识库】调整NUMBER精度,再执行统计信息收集高级包偶现数据库异常退出
[问题分类]功能使用 [关键字]NUMBER类型精度修改,统计信息收集 [问题描述]存量的表将NUMBER类型的字段精度从小精度调整为大精度时,数据库收集这张业务表的统计信息时,会导致数据库异常退出. ...
- sicp每日一题[1.42]
Exercise 1.42 Let f and g be two one-argument functions. The composition f after g is defined to be ...
- 6.24Win&linux&分析后门 勒索病毒分析
操作系统应急响应 1.常见危害 暴力破解.漏洞利用.流量攻击(危害不确定) 木马控制(Webshell.PC木马等),病毒感染(挖矿.蠕虫.勒索等) 2.常见分析 计算机用户.端口.进程.启动项.计划 ...
- 深度学习批次(batch)、迭代(iteration)、周期(epoch)、前向传播(forward propagation)、反向传播(backward propagation)、学习率(learning rate)概念解释
虽然现在应该是已经熟练掌握这些基础概念的时候,但是我是鱼的记忆,上一秒的事情,下一秒就忘了,除非是重要的人的重要的事情,呜呜呜呜,我这个破脑子. 还是写一下吧,直接GPT出来的(人类之光,欢呼~). ...
- ASP.NET Core – MVC
前言 在 ASP.NET Core – MVC vs Razor Page 里有提到 MVC. 它算是 WebAPI 的抽象. 但是通常 MVC 指的是比较传统的 Website, WebAPI 则是 ...
- ASP.NET Core Library – HtmlSanitizer
介绍 要输出 Raw HTML 最好是先消毒一下. 使用 Library 就可以了. 参考 Github – mganss / HtmlSanitizer 安装 nuget dotnet add pa ...