恶补《操作系统》2_3——王道学习笔记

server/2024/9/23 10:25:13/

2.3_1 进程同步、进程互斥

1、进程同步

指为了完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调他们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。

2、进程互斥

把一个时间段内只允许一个进程使用的资源称为临界资源。

对临界资源的互斥访问,可以在逻辑上分为四个部分:

do{entry section;  //进入区  对访问的资源检查或进行上锁critical section; //临界区(段) 访问临界资源的那部分代码exit section;   //退出区  负责解锁remainder section; //剩余区  其它处理} while(true)

需要遵循的原则:

1)空闲让进。 空的可以直接进去

2)忙则等待。 繁忙不能进去

3)有限等待。 不能让进程等待无限长时间

4)让权等待。 不能进去,不要堵着

2.3_2 进程互斥的软件实现方法(重点

1、单标志法

两个进程在访问完临界区后会把使用临界区的权限教给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予

int turn =0;//p0进程while(turn!=0);critical section;turn = 1;remainder section;//p1进程while(turn!=1);critical section;turn = 0;remainder section;

可以实现互斥

存在的问题:p1要访问的话,必须p0先访问,违背:空闲让进原则

2、双标志先检查

算法思想:设置一个bool数组flag[]来标记自己是否想要进入临界区的意愿,先检查后上锁。

bool flag[2]={false,false};//p1进程while(flag[1]);flag[0]=true;critical section;flag[0]=false;remainder section;//p2进程while(flag[0]);flag[0]=true;critical section;flag[1]=false;remainder section;

主要问题:由于进程是并发进行的,可能会违背 忙则等待 的原则;“检查”和“上锁”并不能一气呵成。

3、双标志后检查

算法思想:设置一个bool数组flag[]来标记自己是否想要进入临界区的意愿,不过是先上锁后检查。

bool flag[2]={false,false};//p1进程flag[0]=true;while(flag[1]);critical section;flag[0]=false;remainder section;//p2进程flag[0]=true;while(flag[0]);critical section;flag[1]=false;remainder section;

主要问题:由于进程是并发进行的,可能会两个同时上锁,都进不去,违反 空闲让进 有限等待 原则,从而会饥饿。

4Peterson 算法

主动让对方先使用处理器(孔融让梨)

bool flag[2]={false,false};int turn=0;//p1进程flag[0]=true;turn=1;while(flag[1]&&turn==1);critical section;flag[0]=false;remainder section;//p2进程flag[1]=true;turn=0;while(flag[0]&&turn==0);critical section;flag[1]=false;remainder section;

遵循空闲让进、忙则等待、有限等待三个原则,但是未遵循 让权等待(卡在while循环)的原则。

2.3_3 进程互斥的硬件实现方法

1、中断屏蔽方法

关中断(不允许进程中断)

临界区

开中断

简单、高校

多处理机,可能会同时访问临界资源

使用OS内核进程

2TestAndSetTSL指令)

TSL是用硬件实现的,上锁、检查一气呵成

不满足让权等待,会盲等

C语言描述逻辑:

//true表示已经上锁bool TestAndSet(bool *lock){bool old;old=*lock;*lock=true;return old;}​//以下是使用TSL指令实现互斥的算法逻辑while(TestAndSet (&lock));//上锁并检查临界区代码段lock=false; //解锁​

3Swap指令

别称:Exchange指令、XCHG指令

Swap指令是用硬件实现的

//true表示已经上锁void Swap(bool *a,bool *b){bool temp;temp=*a;*a=*b;*b=temp;}​//以下是使用Swap指令实现互斥的算法逻辑bool old=true;while(old=true)Swap(&lock,&old);临界区代码段lock=false; //解锁//剩余代码段

简单;适用多处理机;不能让权等待

2.3_4 信号量机制

信号量:信号量是一种变量,表示系统中某种资源的数量;

一对原语:waitS)原语和signalS)原语,分别简称PS)、VS),这一对原语可以对信号量进行操作。

1、整形信号量

用一个整数表示系统资源的变量,用来表示系统中某种资源的数量

int S=1;void wait(int S){ //wait原语,相当于:“进入区”(检查和上锁一气呵成)while(S<=0); //如果资源数不够,就意志循环等待S=S-1;    //如果资源数够,则占用一个资源}
void signal(int S){//signal原语,相当于“退出区”S=S+1;    //使用完资源后,在退出区释放资源}

可能会出现盲等

2、记录型信号量(重点

记录型数据结构表示的信号量

//记录型信号量的定义typedef struct{int value;struct process *L;} semaphore;//某进程需要使用资源时,通过wait原语申请void wait (semaphore S){S.value--;if(S.value<0){block (S.L);//将该进程加入到消息队列中}}//进程使用完资源后,通过signal原语释放void signal (semaphore S){S.value++;if(S.valie<=0){wakeup(S.L);}}

除非特别说明,否则默认S为记录型信号量

2.3_5 用信号量机制实现进程互斥、同步、前驱关系(重点

1、实现进程互斥

设置互斥信号量mutex,初值为1mutex表示 “进入临界区的名额”

对不同的临界资源需要设置不同的互斥信号量(只有1个名额)

PV必须成对出现,P申请,V释放

2、实现进程同步

1)保证一前一后的操作顺序

2)设置同步信号量S,初始为0

3)前VP:在前操作之后执行VS);在后操作之后执行PS

3、实现进程的前驱关系(多级同步)

1)要为每一对前驱关系各设置一个同步变量

2)在前操作之后对相应的同步变量执行V操作

3)在后操作之前对相应的同步变量执行P操作

———————————下面介绍几个经典进程同步/互斥问题——————————

2.3_6 生产者-消费者问题(互斥、同步综合问题)

  1. 只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待;
  2. 只有缓冲区不空时,消费者才能从中取出产品,否则必须等待;
  3. 缓冲区是临界资源,各个进程互斥访问;(如果同时访问,可能会产生数据覆盖的问题)
  4. 实现互斥P操作要放在实现同步P操作之后,不能交换顺序,不然会发生死锁;(V操作可以交换)
  5. V操作不会导致进程发生阻塞的状态,所以可以交换;
  6. 相同的操作不要放在临界区,不然并发度会降低;

2.3_7 多生产者-多消费者模型

在生产-消费者问题中,如果缓冲区大小为1,那么有可能不需要设置互斥信号量就可以实现互斥访问缓冲区;分析同步问题是,应该从事件的角度来考虑。

PV操作:

互斥:在临界区前后分别PV

同步:前VP

2.3_8 吸烟者问题

解决可以让生产多个产品的单生产者问题提供一个思路;

若一个生产者要生产多种产品(或者说会引发多种前驱事件),那么各个V操作应该放在各自对应的事件发生之后的位置。


http://www.ppmy.cn/server/14430.html

相关文章

自动化测试用例设计

知人者智&#xff0c;自知者明。大家好&#xff0c;给大家分享一下关于自动化测试用例的设计心得&#xff0c;首先完整的熟悉业务是第一步要做的&#xff0c;不熟悉业务的前提下不会设计出高效且合理的用例&#xff0c;其次是我们要有明确的测试目标&#xff0c;确保我们写的每…

07_c/c++开源库protobuf序列化

1.简介与安装 简介: 无, 懂的都懂 安装 sudo apt install protobuf-compiler protobuf-c-compiler libprotobuf-dev 编译依赖 pkg-config --cflags --libs protobuf -pthread -lprotobuf -pthread 编译选项: -pthread 链接选项: -lprotobuf -pthread 2.实例 1.代码 实例…

如何创建默认的docker0网桥

背景 重启docker服务之后&#xff0c;发现并没有创建默认的docker0网桥&#xff0c;所以导致端口无法映射&#xff0c;容器内IP为127.0.0.1。重启服务后&#xff0c;仍然没有docker0网桥的出现。 分析 docker0网桥是docker默认创建的虚拟网桥。但是有时候会发现&#xff0c;d…

在 vue3 中使用高德地图

前言&#xff1a;定位地图位置所需要的经纬度&#xff0c;可以通过 拾取坐标 获取。 一&#xff1a;快速上手 1. 安装依赖 npm install amap/amap-jsapi-loader # or pnpm add amap/amap-jsapi-loader # or yarn add amap/amap-jsapi-loader 2. 创建组件 src/components/Ma…

图形预处理工具_CogAffineTransformTool

CogAffineTransformTool CogAffineTransformTool工具能够对图像中仿射矩形内的区域进行变换&#xff0c;产生一个矩形的输出图像。这个工具能够消除仿射矩形的旋转和倾斜的影响&#xff0c;并且能够设置一个比例参数&#xff0c;以使能够放大或缩小矩形区域内的特征。并则可以…

06.2_c/c++开源库boost_coroutine2 协程库

1.安装与说明 安装 sudo apt install libboost-coroutine1.71-dev 编译链接 libboost-coroutine不支持.pc格式查看, 支持.cmake导入 cat /usr/lib/x86_64-linux-gnu/cmake/boost_coroutine-1.71.0/boost_coroutine-config.cmake cat /usr/lib/x86_64-linux-gnu/cmake/boost…

父子项目打包发布至私仓库

方法一 在不需要发布至私仓的模块上添加如下代码&#xff1a; <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><configuration><skip>true</skip></configuration>…

关于csgo pubg等游戏卡死问题,原因是英伟达显卡的问题

在正常使用过程中&#xff0c;常常出现&#xff0c;卡死&#xff0c;卡屏问题&#xff0c;经过调查是英伟达驱动的问题&#xff0c;在30系40系明显 显卡超频 本来30系40系就存在不稳定的问题&#xff0c;超频更加导致了此问题&#xff0c;会在驱动中卡死&#xff0c;就是掉驱…