首页 > 系统相关 >【操作系统-进程】PV操作——吸烟者问题

【操作系统-进程】PV操作——吸烟者问题

时间:2022-10-28 23:14:28浏览次数:53  
标签:吸烟者 PV 操作系统 桌子 信号量 while 胶水 烟草

目录

吸烟者问题

假设一个系统有三个抽烟者进程和一个供应者进程。每个抽烟者不停地卷烟并抽掉,但是要卷起并抽掉一支烟,抽烟者需要三种材料:烟草、纸和胶水。三个抽烟者中,第一个拥有烟草,第二个拥有纸,第三个拥有胶水。供应者无限地提供三种材料,供应者每次将两种材料放在桌子上,拥有剩下那种材料的卷烟者卷一根烟并抽掉它,并给供应者一个告诉完成信号,供应者就会放另外两种材料在桌上,这种过程一直重复。

解题步骤

该问题的本质依然是“生产者-消费者”问题,可以用“生产者-消费者”问题的思路去解决。

Step 1. 有几类进程

生产者(){
    while(1){
        
    }
}

吸烟者1(烟草){
    while(1){
        
    }
}

吸烟者2(纸){
    while(1){
        
    }
}

吸烟者3(胶水){
    while(1){
        
    }
}

Step 2. 用中文描述动作

生产者(){
    while(1){
        收到从吸烟者3发来的信号;
        在桌上提供纸和胶水;
        收到从吸烟者1发来的信号;
        在桌上提供烟草和胶水;
        收到从吸烟者2发来的信号;
        在桌上提供烟草和纸;
    }
}

吸烟者1(烟草){
    while(1){
        从桌子上取走纸和胶水;
        吸烟;
        向生产者发送一个信号;
    }
}

吸烟者2(纸){
    while(1){
        从桌子上取走烟草和胶水;
        吸烟;
        向生产者发送一个信号;
    }
}

吸烟者3(胶水){
    while(1){
        从桌子上取走烟草和纸;
        吸烟;
        向生产者发送一个信号;
    }
}

Step 3. 添加 PV 操作,用中文描述里面的操作

【注】//表示新加入的代码。

(1)生产者

生产者(){
    while(1){
        P(从吸烟者3发来的信号); //
        在桌上提供纸和胶水;
        P(从吸烟者1发来的信号); //
        在桌上提供烟草和胶水;
        P(从吸烟者2发来的信号); //
        在桌上提供烟草和纸;
    }
}

吸烟者1(烟草){
    while(1){
        从桌子上取走纸和胶水;
        吸烟;
        V(吸烟者1向生产者发送信号); //
    }
}

吸烟者2(纸){
    while(1){
        从桌子上取走烟草和胶水;
        吸烟;
        V(吸烟者2向生产者发送信号); //
    }
}

吸烟者3(胶水){
    while(1){
        从桌子上取走烟草和纸;
        吸烟;
        V(吸烟者3向生产者发送信号); //
    }
}

(2)吸烟者 1

生产者(){
    while(1){
        P(从吸烟者3发来的信号);
        在桌上提供纸和胶水;
        V(桌子上有纸和胶水); //
        P(从吸烟者1发来的信号);
        在桌上提供烟草和胶水;
        P(从吸烟者2发来的信号);
        在桌上提供烟草和纸;
    }
}

吸烟者1(烟草){
    while(1){
        P(桌子上有纸和胶水吗?有-1,没有阻塞); //
        从桌子上取走纸和胶水;
        吸烟;
        V(吸烟者1向生产者发送信号);
    }
}

吸烟者2(纸){
    while(1){
        从桌子上取走烟草和胶水;
        吸烟;
        V(吸烟者2向生产者发送信号);
    }
}

吸烟者3(胶水){
    while(1){
        从桌子上取走烟草和纸;
        吸烟;
        V(吸烟者3向生产者发送信号);
    }
}

(3)吸烟者 2、吸烟者 3

跟上面是类似的:

生产者(){
    while(1){
        P(从吸烟者3发来的信号);
        在桌上提供纸和胶水;
        V(桌子上有纸和胶水+1); //
        
        P(从吸烟者1发来的信号);
        在桌上提供烟草和胶水;
        V(桌子上有烟草和胶水+1); //
        
        P(从吸烟者2发来的信号);
        在桌上提供烟草和纸;
        V(桌子上有烟草和纸+1); //
    }
}

吸烟者1(烟草){
    while(1){
        P(桌子上有纸和胶水吗?有-1,没有阻塞); //
        从桌子上取走纸和胶水;
        吸烟;
        V(吸烟者1向生产者发送信号);
    }
}

吸烟者2(纸){
    while(1){
        P(桌子上有烟草和胶水吗?有-1,没有阻塞); //
        从桌子上取走烟草和胶水;
        吸烟;
        V(吸烟者2向生产者发送信号);
    }
}

吸烟者3(胶水){
    while(1){
        P(桌子上有烟草和纸吗?有-1,没有阻塞); //
        从桌子上取走烟草和纸;
        吸烟;
        V(吸烟者3向生产者发送信号);
    }
}

(4)缓冲区

每次桌子上只放一件组合,不需要互斥锁。

Step 4. 检查是否出现死锁

不会发生死锁。

Step 5. 定义信号量

offer信号量均表示产品(材料组合)的数量,初始值设为 0。

finish信号量均为前驱后继的关系,因此初始值设为 0。

信号量 offer1 = 0;
信号量 offer2 = 0;
信号量 offer3 = 0;
信号量 finish1 = 0;
信号量 finish2 = 0;
信号量 finish3 = 0;

生产者(){
    while(1){
        P(finish3);
        在桌上提供纸和胶水;
        V(offer1);
        
        P(finish1);
        在桌上提供烟草和胶水;
        V(offer2);
        
        P(finish2);
        在桌上提供烟草和纸;
        V(offer3);
    }
}

吸烟者1(烟草){
    while(1){
        P(offer1);
        从桌子上取走纸和胶水;
        吸烟;
        V(finish1);
    }
}

吸烟者2(纸){
    while(1){
        P(offer2);
        从桌子上取走烟草和胶水;
        吸烟;
        V(finish2);
    }
}

吸烟者3(胶水){
    while(1){
        P(offer3);
        从桌子上取走烟草和纸;
        吸烟;
        V(finish3);
    }
}

网上的代码(与王道的类似)

网上的代码是随机放材料,我写的代码是按顺序依次放材料。

  1. 关系分析。供应者与三个抽烟者分别是同步关系。由于供应者无法同时满足两个或 以上的抽烟者,三个抽烟者对抽烟这个动作互斥。

  2. 整理思路。这里有四个进程。供应者作为生产者向三个抽烟者提供材料。

  3. 信号量设置。信号量 offer1、offer2、offer3 分别表示烟草和纸组合的资源、烟草和 胶水组合的资源、纸和胶水组合的资源。信号量 finish 用于互斥进行抽烟动作。

int random; //存储随机数
semaphore offer1 = 0; //定义信号量对应烟草和纸组合的资源
semaphore offer2 = 0; //定义信号量对应烟草和胶水组合的资源
semaphore offer3 = 0; //定义信号量对应纸和胶水组合的资源
semaphore finish = 0; //定义信号量表示抽烟是否完成

//供应者
while(1){
    random = 任意一个整数随机数;
    random = random % 3;
    if (random == 0)
        V(offerl) ; //提供烟草和纸
    else if (random == 1) 
        V(offer2);  //提供烟草和胶水
    else
        V(offer3)  //提供纸和胶水
    // 任意两种材料放在桌子上,并等待抽烟者抽烟后将 finish 设置为 1
    P(finish);//抽烟者已经使用完材料,需要继续提供材料
}

//拥有烟草者
while(1){
    P (offer3);
    // 拿纸和胶水,卷成烟,抽掉;
    V(finish);
}

//拥有纸者
while(1){
    P(offer2);
    // 烟草和胶水,卷成烟,抽掉;
    V(finish);
}

//拥有胶水者
while(1){
    P(offer1);
    // 拿烟草和纸,卷成烟,抽掉;
    v(finish);
}

标签:吸烟者,PV,操作系统,桌子,信号量,while,胶水,烟草
From: https://www.cnblogs.com/Mount256/p/16837782.html

相关文章

  • Linux操作系统系列:记一次非Lvm文件系统空间扩容
    1、关闭虚拟机,更改磁盘空间大小,如下图: 2、在系统层次发现磁盘已经识别到更改的大小,如下图: 3、但是目录空间还是原来的大小,如下图:4、安装growpart工具,yuminstallcloud-u......
  • 什么是IPv6?IPv6比IPv4有什么优点-中科三方
    IPv6是网络层协议的第二代标准协议,它是IETF设计的一套规范,是IPv4的升级版本。IPv4协议是目前广泛部署的互联网协议。在互联网发展初期,IPv4以其协议简单、易于实现、互操作......
  • 操作系统-线程的调度方法---进程间通信--线程间的通信方式
    文章目录​​线程的调度方法有哪些:​​​​先来先服务(FirstComeFirstService,FCFS)​​​​短作业优先(ShortestJobFirst,SJF)​​​​优先级队列(PriorityQueue)​​​​抢......
  • 操作系统–前言05--存储器-缓存
    存储器分级策略不能用一块存储器来解决所有的需求,那就必须把需求分级。一种可行的方案,根据数据的使用频率使用不同的存储器:高频使用的数据,读写越快越好,因此用最贵的材料,放到......
  • 操作系统-1.1_1概念功能和目标
    操作系统的概念功能和目标熟悉的操作系统:windows,安卓,ios,linux概念应用程序:QQ,浏览器等操作系统:负责关系协调硬件,软件等计算机资源的工作为上层的应用程序,用户提供简......
  • 利用PV操作实现进程的同步的理论意义
    进程的同步是由于进程间合作引起的相互制约的问题,要实现进程的同步可用一个信号量与消息联系起来。当信号量的值为0时表示希望的消息未产生,当信号量的值为非0时表示希望的消......
  • 不同角度理解线程的状态(操作系统 & Java API)
    3.12五种状态(操作系统层面)这是从操作系统层面来描述的【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程关联【可运行状态】(就绪状态)指该线程......
  • k8s pod,ns,pv 强制删除
    一、强制删除pod$kubectldeletepod<your-pod-name>-n<name-space>--force--grace-period=0解决方法:加参数--force--grace-period=0,grace-period表示过渡存活......
  • Qt编写的视频播放综合应用示例(qmedia/ffmpeg/vlc/mpv/海康sdk等)
    一、功能特点1.1基础功能支持各种音频视频文件格式,比如mp3、wav、mp4、asf、rm、rmvb、mkv等。支持本地摄像头设备,可指定分辨率、帧率。支持各种视频流格式,比如rtp、......
  • IPv6
    讲完了基本的IP原理,介绍了传统的IPv4协议族的基本知识,现在我觉得可以升一级讲讲现在全球都在主推的IPv6协议,简单介绍一下发展历程,我觉得这一部分还是可以了解一下历程才知......