进程相互作用之信号量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)的数据结构为记录型数据结构一个值和一个指针,指针指向等待该信号量的下一个进程.信号量的值与相应资源的使用情况有关,在操作系统中,信号量用 ...
随机推荐
- [最新] Chrome 添加 Cookie 标红的解决方法(测试于119)
最近发现 Chrome 开发人员工具里无法添加 Cookie,输入名称时整行变红,而且不会自动补充域.大小.过期时间等项. 网上搜全都是 Chrome 96 要开 Partitioned Cookie ...
- kubernetes批量删除evicted状态pod
#!/bin/bash # get namespace namespaces=`kubectl get pod -A | grep -i "evicted" | awk '{pri ...
- Playwright 浏览器窗口最大化
实现方式 浏览器启动时,加参数 args=['--start-maximized']: 创建上下文时,加参数 no_viewport=True. from playwright.sync_api im ...
- IE中在线预览PDF文件
今天在项目中偶然遇到一个需要在线查看pdf的需求.在查阅一些资料之后使用了最简单的写法(需要在客户端安装AdbeRdr11000_zh_CN_11.0.0.379.exe软件). 还有其他方法可以实现 ...
- Mac安装Adobe PS_AE_PR等系列软件提示错误代码146怎么办?
在安装Mac版Adobe系列软件的时候,不管PS.AE.PR.AI等,如果出现错误代码146,下面两个方法能够轻松解决. 解决方法一:需要我们打开「系统设置」-「隐私与安全」-「App管理」,打开「i ...
- 一文剖析TCP三次握手、四次挥手
TCP三次握手四次挥手 问题 TCP建立连接为什么是三次握手,而不是两次或四次? TCP,名为传输控制协议,是一种可靠的传输层协议,IP协议号为6. 顺便说一句,原则上任何数据传输都无法确保绝对可靠, ...
- docker高级篇第二章-分布式存储之实战案例:主从容错切换迁移案例
在上一篇,学会了3主3从的Redis集群搭建.那么接下来,我们就来学习Redis集群主从容错切换迁移案例 本次案例从模拟两个场景 1:数据读写存储 a:一个新key数据来了,是否会按照预设的进入槽中? ...
- 根据Uri,Cursor没有获取到对应的属性
Android: 背景:调用摄像头,拍摄视频,指定保存的地址,但是返回的Cursor文件,只有名称和大小的属性,没有其他诸如时长,连ID属性都没有 使用 cursor.getInt(cursor.ge ...
- 【YashanDB知识库】用户密码带@字符时exp和imp无法使用
[问题分类]数据导入导出 [关键字]YAS-00404.数据导入导出.密码.特殊字符@.exp.imp [问题描述] 当用户密码带@字符时,使用exp和imp导入导出数据,使用转义符仍然出现报错 且y ...
- [Udemy] AWS Certified Data Analytics Specialty - 4.Analysis
Kinesis Data Analytics Analytics 可以和 Lambda集成 RANDOM_CUT_FOREST, 异常检测算法 OpenSearch = ElasticSearch O ...