【计算机操作系统】课程 作业三 进程同步与互斥 408考研真题

news/2024/10/26 13:51:39/

作业三 进程同步互斥

        这两个问题都是关于进程同步互斥的经典问题,它们可以通过信号量机制来解决。信号量(semaphore)是一种用于控制多个进程对共享资源访问的同步机制。信号量可以是二进制的(只能取0或1),也可以是计数信号量(可以取非负整数值)。

题目一(2009真题):

        3 个进程 P1、P2、P3 互斥地使用一个包含 N(N > 0)个单元的缓冲区。P1 每次用 produce() 生成一个正整数,并用 put() 将其送入缓冲区的某一空单元中 ;P2每次用 getodd() 从该缓冲区中取出一个奇数,并用 countodd() 统计奇数的个数 ;P3 每次用geteven() 从该缓冲区中取出一个偶数,并用 counteven() 统计偶数的个数。

        请用信号量机制实现这 3 个进程的同步互斥活动,并说明所定义的信号量的含义。要求用伪代码描述。

解答:

问题分析:

  • 同步问题:n个缓冲区单元,缓冲区有空位置时才能写;有奇数才能读出奇数,有偶数才能读出偶数。用前V后P实现。
  • 互斥问题:三个进程彼此互斥访问缓冲区。一般都是对于一个缓冲区或者本质上是缓冲区的变量进行访问,这时候就要用PV操作将对于这个信号量的访问夹在中间。

        观察出这是一个生产者消费者问题,由于只有一个缓冲区,有多个商品(奇数和偶数),P1生产奇数和偶数,P2消费奇数,P3消费偶数,明显这是一个多生产者多消费者单缓冲区问题,对于这类问题,只需要将标准生产者消费者问题模型中的full信号量拆分成多个商品的信号量。

        我们需要定义几个信号量来实现同步互斥

  1. mutex:一个二进制信号量,用于控制对缓冲区的互斥访问。
  2. empty:一个计数信号量,表示缓冲区中空闲单元的数量。
  3. odd:一个计数信号量,表示缓冲区中奇数的数量。
  4. even:一个计数信号量,表示缓冲区中偶数的数量。

伪代码实现如下:

// 定义信号量
semaphore mutex = 1;    // 缓冲区互斥信号量。互斥访问缓冲区
semaphore empty = N;    // 缓冲区空闲位置数量。缓冲区中有n个单元
semaphore odd = 0;      // 缓冲区奇数数量
semaphore even = 0;     // 缓冲区偶数数量// P1进程
P1: while true dox = produce() // 生成一个数据P(empty) // 等待空闲单元。判断缓冲区是否有空单元P(mutex) // 进入缓冲区。缓冲区是否被占用,互斥访问缓冲区put(x) // 将x放入缓冲区if x % 2 == 1 thenV(odd) // 增加奇数计数elseV(even) // 增加偶数计数V(mutex) // 释放缓冲区V(empty) // 增加空闲单元计数。缓冲区空位数量加一
end while// P2进程
P2: while true doP(odd) // 等待奇数。有奇数才能取奇数出来P(mutex) // 进入临界区x = getodd() // 取出一个奇数V(mutex) // 离开临界区countodd() // 统计奇数个数
end while// P3进程
P3: while true doP(even) // 等待偶数P(mutex) // 进入临界区x = geteven() // 取出一个偶数V(mutex) // 离开临界区counteven() // 统计偶数个数
end while

举一反三

        设自行车生产线上有一个传送带,其中有 N (N≥3) 个位置,每个位置可存放一个车架或者一个车轮,设有3名工人,进程P1表示工人1每次加工一个车架并放入传送带,进程P2表示工人2每次加工一个车轮并放入传送带,进程P3表示工人3每次从传送带上取出一个车架和两个车轮并组装成一辆自行车。请用信号量机制实现这三个进程的同步互斥活动,并说明所定义的信号量的含义(要求用伪代码描述)。

参考答案:

semaphore mutex = 1;    // 缓冲区互斥信号量
semaphore empty = N;    // 缓冲区空闲位置数量
semaphore weel = 0;    // 车轮数量
semaphore frame = 0;    // 车架数量
semaphore weel_empty = N-1;    // 剩余车轮空位数量名额
semaphore frame_empty = N-2;    // 剩余车架空位数量名额cobegin
Process P1() {while(1) {加工一个车架;P(frame_empty);    // 占用缓冲区可放置车架数量名额P(empty);    // 占用一个缓冲区空位置P(mutex);车架放入缓冲区中;V(mutex);V(frame);    // 车架数量+1}
} 
Process P2() {while(1) {加工一个车轮;P(weel_empty);    // 占用缓冲区可放置车轮数量名额P(empty);    // 占用一个缓冲区空位置P(mutex);车轮放入缓冲区中;V(mutex);V(wheel);    // 车轮数+1}
} 
Process P3() {while(1) {P(frame);    // 取出一个车架P(mutex);缓冲区中取一个车架;V(mutex);V(empty);    // 空位+1;V(frame_empty);    // 释放一个缓冲区可放置车架数量名额P(wheel);P(wheel);P(mutex);缓冲区中取两个车轮;V(mutex);V(empty);V(empty);V(weel_empty);    // 释放一个缓冲区可放置车轮数量名额V(weel_empty);    // 释放一个缓冲区可放置车轮数量名额组装为一辆车;}
} 
coend

考点:生产者消费者问题。

题目二:

        如下图所示,get、copy和put三个进程共用两个缓冲区s和t (其大小每次存放一个记录) ,get 进程负责不断地把输入记录输入缓冲区s 中,copy 进程负责从缓冲区s 中取出记录复制到缓冲区t 中,而put 进程负责从缓冲区t 中取出记录打印。

        试用PV操作实现这三个进程之间的同步,并写出伪代码描述。

 解答:

问题分析:

  • 缓冲区 s:用于暂存 get 进程获取的记录。

  • 缓冲区 t:用于暂存 copy 进程从缓冲区 s 复制过来的记录,等待 put 进程打印。

  • 互斥访问:由于缓冲区 s 和 t 的大小都为1,任何时候只能有一个进程访问任一缓冲区,以避免数据冲突。

  • 同步操作:需要确保 get 进程在缓冲区 s 为空时等待,copy 进程在缓冲区 s 有数据时读取,在缓冲区 t 为空时等待,put 进程在缓冲区 t 有数据时读取。

  • P操作:等待(Proberen)操作,如果信号量的值大于0,则将其减1;如果为0,则阻塞进程。

  • V操作:信号(Verhogen)操作,将信号量的值加1,如果有进程因等待该信号量而被阻塞,则唤醒它们。

信号量定义:

  • s_empty:表示缓冲区 s 的空闲状态。初始值为1,因为一开始缓冲区 s 是空的。

  • t_full:表示缓冲区 t 的占用状态。初始值为0,因为一开始缓冲区 t 是空的。

  • mutex_s 和 mutex_t:用于确保对缓冲区 s 和 t 的互斥访问。初始值均为1。

伪代码实现如下:

// 信号量定义
Semaphore s_empty = 1; // 缓冲区s的空闲位置,初始为1
Semaphore t_full = 0; // 缓冲区t的满位置,初始为0
Semaphore mutex_s = 1; // 缓冲区s的互斥信号量,初始为1
Semaphore mutex_t = 1; // 缓冲区t的互斥信号量,初始为1// get 进程
GET: while true doP(s_empty) // 等待缓冲区 s 空闲P(mutex_s) // 进入缓冲区 s 的临界区record = read_input() // 读取输入记录V(mutex_s) // 离开缓冲区 s 的临界区put record into s // 将记录放入缓冲区 sV(t_full) // 通知缓冲区 s 已满
end while// copy 进程
COPY: while true doP(t_full) // 等待缓冲区 s 有数据P(mutex_s) // 进入缓冲区 s 的临界区record = get from s // 从缓冲区 s 取出记录V(mutex_s) // 离开缓冲区 s 的临界区P(mutex_t) // 进入缓冲区 t 的临界区put record into t // 将记录放入缓冲区 tV(mutex_t) // 离开缓冲区 t 的临界区V(s_empty) // 通知缓冲区 s 已空V(t_full) // 通知缓冲区 t 已满
end while// put 进程
PUT: while true doP(t_full) // 等待缓冲区 t 有数据P(mutex_t) // 进入缓冲区 t 的临界区record = get from t // 从缓冲区 t 取出记录V(mutex_t) // 离开缓冲区 t 的临界区print record // 打印记录V(s_empty) // 通知缓冲区 s 已空
end while


http://www.ppmy.cn/news/1542129.html

相关文章

雷池社区版有多个防护站点监听在同一个端口上,匹配顺序是怎么样的

如果域名处填写的分别为 IP 与域名,那么当使用进行 IP 请求时,则将会命中第一个配置的站点 以上图为例,如果用户使用 IP 访问,命中 example.com。 如果域名处填写的分别为域名与泛域名,除非准确命中域名,否…

webRTC搭建:STUN 和 TURN 服务器 链接google的有点慢,是不是可以自己搭建

如果使用 Google 提供的 STUN/TURN 服务器速度较慢,你完全可以自己搭建 STUN 和 TURN 服务器。这有助于提升网络连接速度和稳定性,特别是在需要穿透 NAT 或防火墙的网络环境下。 下面是如何自己搭建 STUN 和 TURN 服务器的具体步骤: 1. 选择…

微软推新模型OmniParser:让GPT-4V秒懂屏幕截图内容,指哪懂哪

还记得那个号称“看图说话”神器GPT-4V吗?它能理解图片内容,还能根据图片执行任务,简直是懒人福音!但它有个致命弱点:眼神不太好! 想象一下,你让GPT-4V帮你点个按钮,它却像个“屏幕瞎子”一样,到处乱点,是…

Find My平板键盘|苹果Find My技术与键盘结合,智能防丢,全球定位

‌平板键盘的主要用途包括提高输入效率、支持轻量化办公、提供丰富的文本编辑功能以及快捷操作。相比于直接在屏幕上打字,使用键盘可以显著提升输入速度,减少输入错误,特别是对于需要大量文字输入的场景,如写作、记录笔记等‌。平…

【GIT】Visual Studio 中 Git 界面中, 重置 和 还原

在 Visual Studio 的 Git 界面中,“重置” 和 “还原” 是两个常用的 Git 操作。它们的主要区别在于应用场景和影响范围。 1. 重置(Reset) 重置用于更改当前分支的提交历史,通常用于撤销或删除某些提交。重置操作可能会更改 Git…

Spring Boot助力的厨艺互动平台开发指南

2 相关技术 2.1 Spring Boot框架简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Sprin…

node和npm版本冲突

问题描述: 解决办法: 一、 查看自己当前的node和npm版本 node -v npm -v 二、 登录node官网地址 node官网地址 https://nodejs.org/zh-cn/about/previous-releases 查看与自己node版本兼容的是哪一版本的npm,相对应进行更新即可。 三 升级node 下载最…

PyTorch模块介绍

PyTorch 是一个开源的深度学习框架,主要用于深度学习和计算图的构建与训练。它由几个核心模块组成,每个模块都有特定的功能。以下是 PyTorch 的主要模块及其功能介绍: 1. torch 这是 PyTorch 的核心模块,包含了所有基础的张量操作和数学运算。它支持张量的创建、数学运算…