03并发进程

news2024/11/18 23:31:06

文章目录

  • 哲学家进餐问题
    • 1.利用结构型信号量解决哲学家进餐问题
      • 解决方案1:每次最多允许四位哲学家就餐
    • 2.利用AND型信号量解决哲学家进餐问题
  • 生产者-消费者问题
    • 1.利用结构型信号量解决生产者-----消费者问题
      • 单缓冲区生产者-消费者问题
      • 多缓冲区
    • 2.利用AND型信号量解决生产者-----消费者问题
  • 读者-写者问题
    • 1.利用结构型信号量解决读者-----写者问题
    • 2.利用信号量集机制解决读者-----写者问题
  • 理发师问题
    • 结构型信号量解决理发师问题
  • 吸烟者问题

信号量的应用问题总结

哲学家进餐问题

五位哲学家围坐一张圆桌,桌子中央放有一盘面条,桌上放五根筷子,每位哲学家只能拿起与他相邻的两根筷子吃饭

哲学家的生活方式是交替地进行思考和进餐
在这里插入图片描述

1.利用结构型信号量解决哲学家进餐问题

数据结构:每根筷子都是一个临界资源,都应定义一个信号量,为五根筷子定义一个信号量数组,每个信号量的初值为1

semaphore chopstick[5];
for (int i=0;i<5;i++) chopstick[i]=1;
//操作描述:第i位哲学家的活动如下: 
Process philosopher_i()
{
      while(true)
       { 
        thinking();
		P(chopstick [ i ]);
		P(chopstick [(i+1) mod 5]);
		eating ;
		V(chopstick [ i ]);
		V(chopstick [(i+1)mod 5]);	
		thinking() ; 
              } 	
}

算法分析:
若每个哲学家都各自拿起他左边的一根筷子,然后再去拿他右边的筷子时,将都拿不到右边的筷子,大家又都不会放下手中的筷子,大家在相互等待别人释放筷子,系统于是进入死锁状态

解决方案1:每次最多允许四位哲学家就餐

semaphore chopstick[5], s=4;
for (int i=0;i<5;i++) chopstick[i]=1;
process philosopher_i()
{
       while(true)
	  {	thinking();
	    P(s);
		P(chopstick[i]);
		P(chopstick[(i+1) mod 5]);
		eating ;
		V(chopstick[i]);
		V(chopstick[(i+1) mod 5]);
		V(s);	
		thinking() ; 
}
}

解决方案2:分奇偶号
奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子
偶数号哲学家先拿他右边的筷子,然后再去拿左边的筷子
解决方案3:仅当哲学家的左右两根筷子均可用时,才允许他拿起筷子进餐

2.利用AND型信号量解决哲学家进餐问题

Semaphore chopstick[5];
for (int i=0;i<5;i++) chopstick[i]=1; 
cobegin
Process philosopher_i(){
	   while(true){  
        thinking ;
		SP(chopstick[i],chopstick[(i+1)mod 5]);
	    eating ;
	   	SV(chopstick[i],chopstick[(i+1) mod 5]);
	}
}
coend

生产者-消费者问题

1.利用结构型信号量解决生产者-----消费者问题

数据结构:
含有n个缓冲区的公用缓冲池
互斥信号量mutex:实现诸进程对缓冲池的互斥使用,一次仅允许一个进程读或写公用缓冲池,初值为1
资源信号量empty:记录空缓冲区个数,初值为n
资源信号量full:记录满缓冲区个数,初值为0

操作要求:多个生产者进程之间、多个消费者进程之间、生产者进程与消费者进程之间均能正确同步

单缓冲区生产者-消费者问题

int B;
Semaphore empty, full;
empty=1;
full=0;

cobegin
process producer (){
	   while(true)
	   {
            produce();
            p(empty);
            Append() to B; 
            V(full);
       }
}

Process consumer()
{
   while(true)
  {
        p(full);
        take() from B;
        v(empty);
        consume();
   }
}
coend

多缓冲区

对于m个生产者和n个消费者,它们共享可存放k件产品的缓冲区
为了使其协调工作,必须使用一个信号量mutex,限制生产者和消费者互斥地对缓冲区进行存取
另用两个信号量empty和full,以保证生产者不向已满的缓冲区中放入产品,消费者不从空缓冲区中取产品

item B[k];
Semaphore empty, full, mutex;
empty=k;full=0;mutex=1;
cobegin
process producer_i (){
	   while(true)
       {
            produce();
            p(empty);
            p(mutex);
            append to B[in]; 
            in= (in+1)%k;
            V(mutex);
            V(full);
    }
}

Process consumer_j()
{
     while(true)
    {
        p(full);
        P(mutex);
        take() from B[out];
        out=(out+1)%k;
        v(mutex);
        v(empty);
        consume();
     }
}
coend

2.利用AND型信号量解决生产者-----消费者问题

semaphore  mutex , empty , full : 
semaphore = 1 , n , 0 ;
item buffer [n];
int in , out= 0 , 0 ;
begin
	parbegin
		producer : 
		   begin
			while(true)
   			{
				produce an item in nextp ;
				SP(empty,mutex);
				Buffer(in)= nextp ;
				in =(in+1) mod n ;
				SV(mutex,full);
			}  
			end
        consumer :
           begin
		     while(true)
		    {
			    SP(full,mutex);
			    nextc = buffer(out);
			    out =(out + 1) mod  n ;
			    SV(mutex,empty);
		     }
	        end 
	 parend
end


读者-写者问题

若干Reader进程和Writer进程共享一个数据文件,允许多个Reader进程同时读一个共享对象,但不允许一个Writer进程与其它Reader进程或Writer进程同时访问共享对象

情况分析: 如果读者数目ReadCount为0,则可能有也可能没有写者在写
如果读者数目ReadCount不为0,则不会有写者在写,请求读的读者便可读
如果读者数目ReadCount为0,又没有写者在写,则请求写的写者才能写

1.利用结构型信号量解决读者-----写者问题

数据结构:
互斥信号量mutex:用于Reader与Writer、Writer与Writer之间的互斥,初值为1;
ReadCount:正在读的进程数目,初值为0
互斥信号量 rmutex:用于Reader与Reader 互斥访问整型量ReadCount,初值为1

semaphore rmutex , mutex = 1 , 1 ;
int ReadCount = 0;
parbegin
	Reader:
       {
		P(rmutex);
	    if (ReadCount==0) then  P(mutex);
		ReadCount = ReadCount + 1 ;
		V(rmutex);
		read ;
		P(rmutex);
		ReadCount= ReadCount - 1 ;
        if (ReadCount==0) then V(mutex);
		V(rmutex);
       }
     Writer 
    {	
	   P(mutex);
	   write ;
	   V(mutex);
     }
parend

2.利用信号量集机制解决读者-----写者问题

要求 :规定最多允许RN个读者同时读
数据结构:
读者数目信号量L ,初值为RN;
信号量mx,表示有无写者在写,初值为1

int RN;
semaphore L , mx = RN , 1 ;
parbegin
		Reader
		{
			SP(L , 1 , 1 );
			SP(mx, 1 , 0);
			read ;
			SV( L , 1);
		}
		writer 
       {
		SP(mx , 1 , 1 ; L , RN , 0);
		write ;
		SV(mx , 1);
	   }
parend

理发师问题

理发店有一位理发师、一把理发椅和n把供等候理发的顾客坐的椅子 如果没有顾客,理发师便在理发椅上睡觉 当一个顾客到来时,它必须叫醒理发师
如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,他们就坐下来等待,否则就离开

结构型信号量解决理发师问题

int waiting=0;      //等候理发的顾客数 
int  CHAIRS=0;          //为顾客准备的椅子数
semaphore   customers, barbers, mutex;
customers = 0; barbers= 0; mutex= 1;
Procedure barber;
{
Whlie(1)
{
  P(customers);            //若无顾客,理发师睡眠
  P(mutex);                //进程互斥
  waiting = waiting – 1;   //等候顾客数少一个
  V(barbers);               //理发师去为一个顾客理发
  V(mutex);                 //开放临界区
  cut-hair( );              //正在理发
   }
}

procedure customer
{
  P(mutex);                 //进程互斥
  if (waiting<CHAIRS) //看看有没有空椅子
  {
     waiting = waiting+1;  //等候顾客数加1
     V(customers);          //必要的话唤醒理发师
     V(mutex);              //开放临界区
     P(barbers);            //无理发师, 顾客坐着养神
     get_haircut();
  }
  else V(mutex);            //人满了,走吧!
}

吸烟者问题

三名吸烟者在同一个房间内,还有一位香烟供应者,为了制造并抽掉香烟,每位吸烟者需要拥有三样东西:烟草、纸和火柴,供应者有丰富的货物提供。三位吸烟者中,第一个人有自己的烟草,第二个人有自己的纸,第三个人有自己的火柴,供应者随机地将两样东西放在桌子上,允许一位吸烟者进行对健康不利的吸烟,当吸烟者完成吸烟后唤醒供应者,供应者再把两样东西放在桌子上,唤醒另一位吸烟者。试采用信号量和PV操作编写他们同步工作的程序

semaphore S = 1,S1 = 0, S2 = 0,S3 = 0; 
bool flag1,flag2,flag3; /*flage1、flage2、flage3代表烟草、纸、火柴*/
process 供应者( ) 
 {
     while(true) {
     P(S);
     //随机生成整数random
     if(random%3=0)  V(S1);             /*供纸和火柴*/
     else  if(random%3=1)  V(S2);      /*供烟草和火柴*/
          else  V(S3);                  /*供烟草和纸*/
     } 
}

Process Smoker1()
{  
        P(S1);
       制造香烟
       吸烟;
        V(S);
}

Process Smoker2()
{  
       P(S2);
      制造香烟
      吸烟;
       V(S);
}

Process Smoker3()
{  
        P(S3);
       制造香烟
       吸烟;
        V(S);
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/633815.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高并发编程:并发容器

一、概述 常见的容器如下图&#xff0c;我们会挑选高并发中常用的容器进行介绍。 二、ConcurrentHashMap 个ConcurrentHashMap提高效率主要提高在读上面&#xff0c;由于它往里插的时候内部又做了各种各样的判断&#xff0c;本来是链表的&#xff0c;到8之后又变成了红黑树&a…

详细讲解!selenium:解决页面元素display:none的方法

目录 前言&#xff1a; 1、具体问题 2、解决方案 代码解析&#xff1a; 结尾&#xff1a; 前言&#xff1a; 在进行 Web 自动化测试时&#xff0c;页面元素的可见性对测试结果的准确性和稳定性至关重要。然而&#xff0c;有些时候页面元素会被设置为 display:none&#x…

亚马逊云科技出海日,助推出海业务全球拓展突飞猛进

出海路漫漫&#xff0c;企业开拓全球市场而孤军奋战&#xff0c;常常会感到力不从心。好的产品有了&#xff0c;渠道有了&#xff0c;供应链有了&#xff0c;还要自己从0-1搭建存储、网络和架构&#xff1f;营销季来了想趁机冲一波销量&#xff0c;还要自己运维本地IDC、大促来…

10.无监督学习之K-means算法

10.1 无监督学习的定义 监督学习&#xff1a;我们有一些列标签&#xff0c;然后用假设函数去拟合它 无监督学习&#xff1a;给出的数据不带任何标签。对于无监督学习来说&#xff0c;需要做的就是将数据输入到算法中&#xff0c;让算法找到一些隐含在数据中的结构&#xff0c;通…

C语言—程序环境和预处理

程序环境和预处理 程序的翻译环境和执行环境编译、链接翻译环境编译预处理&#xff08;预编译&#xff09;编译汇编 链接 编译环境几个阶段的总结 运行环境&#xff08;执行环境&#xff09;预处理详解预定义符号#define#define 定义标识符#define 定义宏#define 替换规则#和##…

【MySQL】数据库中表的操作详解

【MySQL】数据库表的基本操作 一、表的创建二、查看表结构三、修改表结构3.1 添加表中字段3.2 修改表中字段3.3 删除表中字段3.4 修改表名3.5 修改列名 四、删除表 温馨提示&#xff1a;这里的表操作指的是表结构的操作&#xff0c;属于DDL数据定义语言 一、表的创建 CREATE …

hooks组件+例子+底层机制

1.React组件分类 函数组件 1.不具备"状态、ref、周期函数"等内容&#xff0c;第一次渲染完毕后&#xff0c;无法基于组件内部的操作来控制其更新&#xff0c;因此称之为静态组件!。但是具备属性及插槽&#xff0c;父组件可以控制其重新渲染 2.渲染流程简单&#xff…

Same Symbol | 哇咔咔!!!盘点一下表达矩阵中重复基因的处理方法!~

1写在前面 医院天天叫我们填问卷&#xff0c;我真是不能理解。&#x1fae0; 动不动就问我们对医院的福利满意吗&#xff0c;对自己的收入满意吗&#xff0c;觉不觉得工作负荷太重了&#xff1f;&#xff1f;&#xff1f;&#x1f642; 我们满不满意&#xff0c;觉不觉得累&…

大学物理(上)-期末知识点结合习题复习(2)——运动的描述考点总结、质点运动学-牛顿运动定律

目录 运动的描述 期末考点 质点运动学 牛顿运动定律知识点 题1(牛顿第二定律) 题目描述 题解 题2 (圆周运动) 题目描述 题解 运动的描述 期末考点 1.速度和加速度的推导 平均速度平均速度反映的只是在一段时间内位移的变化&#xff0c;如果需要精准的地知道质点在…

chatgpt赋能python:Python如何判断奇偶数?

Python如何判断奇偶数&#xff1f; 作为一门功能强大且容易上手的编程语言&#xff0c;Python具有许多有用的工具和功能。其中之一就是判断奇偶数。在本文中&#xff0c;我们将介绍Python中判断奇偶数的不同方法。 H1&#xff1a;Python中的基本判断方法 Python中最基本的判…

(八)CSharp-泛型协变和逆变(3)

一、协变和逆变 可变性分为三种&#xff1a; 协变、逆变和不变。 协变和逆变&#xff1a; 为泛型接口和泛型委托添加了一个处理类型转换问题的扩展。 问题&#xff1a; 当两个类对象是继承与派生的关系时&#xff0c;由于编译器通过泛型实例化时没法确认它们之间的关系&…

(数组) 1991. 找到数组的中间位置 ——【Leetcode每日一题】

❓1991. 找到数组的中间位置 难度&#xff1a;简单 给你一个下标从 0 开始的整数数组 nums &#xff0c;请你找到 最左边 的中间位置 middleIndex &#xff08;也就是所有可能中间位置下标最小的一个&#xff09;。 中间位置 middleIndex 是满足 nums[0] nums[1] ... num…

FTP协议详解

文章目录 1 FTP概述2 实验环境3 FTP详解3.1 文件传输过程3.2 报文格式3.3 数据连接3.4 主动模式3.5 被动模式3.6 匿名服务器 4 总结 1 FTP概述 FTP为File Transfer Protocol的缩写&#xff0c;即文件传输协议&#xff0c;是TCP/IP 协议族中的协议之一。FTP是一个用于在计算机网…

算法模板(3):搜索(3):图论提高

图论提高 最小生成树 &#xff08;1&#xff09;朴素版prim算法&#xff08; O ( n 2 ) O(n ^ 2) O(n2)&#xff09; 适用范围&#xff1a;稠密图易错&#xff1a;注意有向图还是无向图&#xff1b;注意有没有重边和负权边。从一个集合向外一个一个扩展&#xff0c;最开始只…

(文章复现)面向配电网韧性提升的移动储能预布局与动态调度策略(1)-灾前布局matlab代码

参考文献&#xff1a; [1]王月汉,刘文霞,姚齐,万海洋,何剑,熊雪君.面向配电网韧性提升的移动储能预布局与动态调度策略[J].电力系统自动化,2022,46(15):37-45. 1.基本原理 1. 1 目标函数 本文以最恶劣光伏出力场景下的移动储能配置成本与负荷削减成本最小为目标&#xff0c;建…

(数组) 724. 寻找数组的中心下标 ——【Leetcode每日一题】

❓724. 寻找数组的中心下标 难度&#xff1a;简单 给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#xff0c;那么左侧数之和视为…

2023-6-9

1.网络训练&#xff1a; 在训练前先要看看读取数据的时间&#xff08;常见的性能瓶颈&#xff09;2.import dis dis 是 Python 内置的一个模块&#xff0c;其全称为 “Disassembler for Python bytecode”&#xff0c;用于反汇编 Python 字节码。它可以将 Python 代码编译成字…

视频换天造物实践秒变科幻大片实践记录

视频换天造物实践秒变科幻大片实践记录&#xff0c;过程中遇到些坑&#xff0c;结果还是相当震撼 预装软件&#xff1a; matplotlib scikit-image scikit-learn scipy numpy torch torchvision opencv-python opencv-contrib-python 安装使用的时候可能碰上scikit-image 新版…

傅里叶级数简介

先看动图 将函数f(x) 用 sin(nx) cos(nx) 的形式表示出来的方式就是傅里叶级数 这里有几个使用条件 收敛性&#xff1a;符合迪力克雷收敛条件。简单理解为 f(x) 必须是一个丝滑的曲线。周期性&#xff1a; f(x) 必须是一个周期函数 还有一个基础条件&#xff0c;三角函数具…

element-plus布局排版问题总结(更新ing)

文章目录 el-container空隙修改app组件 el-container空隙 源码-更改了容器的显示&#xff0c;占满屏幕 <template><div class"common-layout"><el-container><el-header><el-row class"el-row1"><el-col :span"12&…