操作系统(4) 进程同步

目录

一、进程同步与互斥

1.同步与互斥的基本概念

(1)临界资源

(2)临界区

(3)同步机制的准则

2.进程同步

3.进程互斥

二、信号量机制

1.整型信号量

2.记录型信号量

三、信号量机制

1.信号量的基本应用

2.实现同步

3.信号量问题分析方法

四、生产者消费者问题

1.问题描述

2.问题分析

3.PV操作问题分析方法

4.如何实现

总结


1.同步与互斥的基本概念

(1)临界资源

  • 是一次仅允许一个进程使用的共享资源。
  • 各进程采取互斥的方式,实现共享的资源称作临界资源。
  • 属于临界资源的硬件:打印机,磁带机等;软件:消息队列,变量,数组,缓冲区等。

(2)临界区

每个进程中访问临界资源的那段代码称为临界区,每次只允许一个进程进入临界区,进入后,不允许其他进程进入。

临界资源的访问过程分为4个部分:

  • 进入区。负责检查是否可以进入临界区,设置正在访问临界资源的标志。
  • 临界区。访问临界资源的那段代码。
  • 退出区。负责解除正在访问临界资源的标志。
  • 剩余区。做其他处理。

(3)同步机制的准则

为禁止两个进程同时进入临界区,同步机制应遵循以下准则:

  • 空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区。
  • 忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待。
  • 有限等待:对请求访问的进程,应保证能在有限时间内进入临界区。
  • 让权等待:当进程不能进入临界区时,应立即释放处理器,防止进程忙等待。

2.进程同步

进程同步也称直接制约关系,它指的是多个进程一起完成某个任务,这些进程因为合作需要在某些位置上协调他们的工作次序而产生了某些制约关系。

3.进程互斥

进程互斥也称间接制约关系。当某个进程A在访问临界区使用临界资源时,另一个B进程必须等待, 直到进程访问结束并释放该临界资源后,B进程才能去访问。


二、信号量机制

信号量机制是一种功能较强的机制,可用来解决互斥和同步问题,它只能被两个标准的原语wait(S)和 signal(S)访问,也可记为"P操作"和"V操作"。

P原语(或称为阻塞原语):负责把当前进程由运行状态转换为阻塞状态,直到另外一个进程唤醒它。操作为申请一个空闲资源(即信号量减1),若成功则退出;若失败则该进程被阻塞。

V原语(或称为唤醒原语):负责把一个被阻塞的进程唤醒。其操作是释放一个被占用的资源(即信号量加1),如果发现有被阻塞的进程则选择一个进行唤醒。

1.整型信号量

整型信号量被定义为一个用于表示资源数目的整型量S。

P和V操作可描述为:

//等待区

wait(S){

while(S<=0);

S=S-1;

}

//退出区

signal(S){

S=S+1;

}

该机制并未遵循"让权等待"的准则,而是使进程处于"忙等"的状态。

2.记录型信号量

记录型信号量是不存在"忙等"现象的进程同步机制。除需要一个用于代表资源数目的整型变量value外,再增加一个进程链表L,用于链接所有等待该资源的进程。

typedef struct{

int value;

struct process *L;

}semaphore;

void wait (semaphore S) {

S. value--;

if(S. value < 0){

//添加进程到等待队列中;

block (S.L);//阻塞态

}

}

void signal (semaphore *S){

S. value++;

if(S. value<=0){

// 唤醒一个等待队列的进程;

wakeup (P);

}

}


三、信号量机制

1.信号量的基本应用

(1)互斥信号量mutex,初值为1

(2)每个每个进程将临界区代码置于P(mutex)和V(mutex)原语之间

(3)必须成对使用P和V原语(在同一进程中),不能次序错误、重复或遗漏:

  • 遗漏P原语则不能保证互斥访问
  • 遗漏V原语则不能在使用临界资源之后将其释放

semaphore mutex=1;

P1 (){

......

P (mutex);

临界区代码段...

V (mutex)

......

}

P2(){

.......

P (mutex);

临界区代码段...

V (mutex);

......

}

2.实现同步

(1)分析什么地方需要实现"同步关系",即必须保证"一前一后"执行的两个操作(或两句代码)。

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

(3)在"前操作"之后执行V(S)

(4)在"后操作"之前执行P(S)

//信号量机制实现同步

semaphore S=0;

P1(){

while (1){

C1;

V(S);

......;

P2(){

while (1){

P(S);

C2;

}

//保证了C1一定是在C2之前

3.信号量问题分析方法

①分析问题,找出同步、互斥关系

②根据资源设置信号量变量

③写出代码过程,并注意P、V操作的位置

④检查代码,模拟机器运行,体验信号量的变化和程序运行过程是否正确。


四、生产者消费者问题

1.问题描述

系统中有一组生产者进程和一组消费者进程,生产者进程每一次生产一个产品放入缓冲区, 消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的"产品"理解为某种数据)。

生产者、消费者共享一个初始为空、大小为n的缓冲区。

只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。

只有缓冲区不空时, 消费者才能从中取出产品,否则必须等待。

缓冲区是临界资源, 各进程必须互斥地访问。

2.问题分析

该问题中出现的主要的两种关系:

①生产者一消费者之间的同步关系:一旦缓冲池中所有缓冲区均装满产品时生产者必须等待消费者提供空缓冲区;一旦缓冲池中所有缓冲区全为空时,消费者必须等待生产者提供满缓冲区。

②生产者一消费者之间的互斥关系:由于缓冲池是临界资源,所以任何进程在对缓冲区进行存

取操作时都必须和其他进程互斥进行。

3.PV操作问题分析方法

①关系分析。找出题目中描述的各个进程,分析它们之间的同步、互斥关系。

②整理思路。根据各进程的操作流程确定操作的大致顺序。

③设置信号量。设置需要的信号量,并根据题目条件确定信号量的初值。

4.如何实现

互斥的实现是在同一个进程中进行一对PV操作。

同步的实现是在两个进程中进行,在一个进程中执行P操作,在另一个进程中执行V操作。

semaphore mutex=1; //互斥信号量

semaphore empty=n; //同步信号量。空闲缓冲区的数量

semaphore full=0; //同步信号量。产品的数量,非空缓冲区的数量

producer (){

while(1){

//生成一个产品;

P(empty); //消耗一个空闲缓冲区

P (mutex) ;

//把产品放入缓冲区;

V (mutex);

V(full); //增加一个产品

}

consumer (){

while(1){

P(full); //消耗一个产品

P (mutex);

//从缓冲区取出一个产品;

V (mutex);

V (empty); //增加一个空闲缓冲区

使用产品;

}

}

注意:实现互斥的P操作一定要放在实现同步的P操作之后。

易错点:实现互斥和实现同步的两个P操作的先后顺序。


总结

本篇对操作系统进程同步的知识内容进行了整理与概述,便于复习与回顾。其中部分内容源自网络,如有侵权,请联系作者删除,谢谢!

相关推荐
IT果果日记19 分钟前
ubuntu 安装 conda
linux·ubuntu·conda
Python私教22 分钟前
ubuntu搭建k8s环境详细教程
linux·ubuntu·kubernetes
羑悻的小杀马特35 分钟前
环境变量简介
linux
小陈phd1 小时前
Vscode LinuxC++环境配置
linux·c++·vscode
是阿建吖!1 小时前
【Linux】进程状态
linux·运维
明明跟你说过2 小时前
Linux中的【tcpdump】:深入介绍与实战使用
linux·运维·测试工具·tcpdump
Komorebi.py3 小时前
【Linux】-学习笔记05
linux·笔记·学习
Mr_Xuhhh3 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
梓仁沐白6 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
内核程序员kevin6 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip