操作系统实验五 理发师问题

合集下载

嗜睡的理发师问题

嗜睡的理发师问题

1、嗜睡的理发师问题:一个理发店由一个有N张沙发的等候室和一个放有一张理发椅的理发室组成。

没有顾客要理发时,理发师便去睡觉。

当一个顾客走进理发店时,如果所有的沙发都已经占用,他便离开理发店;否则,如果理发师正在为其他顾客理发,则该顾客就找一张空沙发坐下等待;如果理发师因无顾客正在睡觉,则由新到的顾客唤醒理发师为其理发。

在理发完成后,顾客必须付费,直到理发师收费后才能离开理发店,试用信号量实现这一同步问题。

int waiting ;//等候理发的顾客数int CHAIRSr;//为顾客准备的椅子数semaphore Customers,babers,mutex;Customers=0;barbers=0;waiting=0;mutex=1;barber( )//理发师进程{while(TRUE){wait(customers); //若无顾客,理发师睡眠wait(mutex);//进程互斥waiting=waiting-1;//等待顾客数少一signal(barbers);//理发师去为一个顾客服务signal(mutex);//离开临界区Cut_hair();}}Customer (int i){wait(mutex);//进程互斥if(waiting<CHAIRS)//看看有没有空椅子{waiting=waiting+1;//等候顾客数加1signal(customers);//必要的话唤醒理发师signal(mutex);//开放临界区wait(barbers);//无理发师,顾客等待get_haircut();//一个顾客坐下等理发}elsesignal(mutex);//人满了,走吧}1、嗜睡的理发师问题:一个理发店由一个有N张沙发的等候室和一个放有一张理发椅的理发室组成。

没有顾客要理发时,理发师便去睡觉。

当一个顾客走进理发店时,如果所有的沙发都已经占用,他便离开理发店;否则,如果理发师正在为其他顾客理发,则该顾客就找一张空沙发坐下等待;如果理发师因无顾客正在睡觉,则由新到的顾客唤醒理发师为其理发。

理发师问题的相关课设

理发师问题的相关课设

一、设计内容与设计要求1.课程设计目的全面熟悉、掌握计算机系统与系统软件基本知识,增强对不同的问题运用和灵活选择合适的数据结构以及算法描述的本领,熟悉编制和调试程序的技巧,掌握分析结果的若干有效方法,进一步提高上机动手能力,增强面向对象程序设计概念,熟悉C++语言编程,养成提供文档资料的习惯和规范编程的思想,为后继课程的实验以及课程设计打下较扎实的基础。

进一步提高上机动手能力,培养使用计算机解决实际问题的能力,为后继课程(数据结构、数据库和JA V A\C#语言编程等课程)的实验以及课程设计,特别是自学、毕业论文的完成打下扎实的基础。

2.课题题目理发店有三个理发师,有三张沙发。

顾客来了理发师正忙可以坐在沙发上。

理发师理完发可以从沙发上叫醒顾客理发。

3.设计要求:主要模块:1、理发师进程模块具有功能:1、有顾客理发师理发2、没有顾客等待3、一个理发师只能理一个顾客4、友好提示5、最多同时理3个顾客5、退出本系统2、顾客模块具有功能:1、友好提示2、理发师忙顾客等待3、理发师闲则顾客理发4、等待的顾客不能超过三个5、退出本系统要求:1)设计正确,方案合理。

2)界面友好,使用方便。

3)程序精炼,结构清晰。

4)设计报告5000字以上,含程序设计说明、系统的功能框图、流程图、源程序清单等。

5)实际操作过程中遇到的问题及解决方法:设计总结及心得体会.6)上机演示。

二、进度安排第18周星期一下午14:00-18:00星期二下午14:00-18:00星期四下午14:00-18:00目录前言 (1)1.系统需求分析 (2)1.1 问题描述 (2)1.2 问题分析 (2)1.3 运行环境分析 (3)2.概要设计 (3)2.1简要介绍 (3)2.2概要设计流程图 (3)3.详细设计 (4)3.1详细设计流程图 (4)3.2采用C++语言定义相关的数据类型。

(5)3.3写出各模块的类C码算法。

(5)4.系统调试 (7)5.程序运行截图结果 (8)5.1 进入程序运行界面 (8)5.2 理发师是否开门营业界面 (9)5.3 理发师开门服务界面 (10)5.4 理发师休息界面 (11)5.5 退出界面 (12)6.心得体会 (12)7.附录 (13)7.1 源代码 (13)7.2 参考文献 (17)8.评分表 (18)前言打瞌睡的理发师问题是一种同步问题的抽象描述。

山东大学操作系统实验五理发师问题报告

山东大学操作系统实验五理发师问题报告

计算机科学与技术学院操作系统实验报告实验题目:理发店问题理发店问题:假设理发店的理发室中有3个理发椅子和3个理发师,有一个可容纳4个顾客坐等理发的沙发。

此外还有一间等候室,可容纳13位顾客等候进入理发室。

顾客如果发现理发店中顾客已满(超过20人),就不进入理发店。

在理发店内,理发师一旦有空就为坐在沙发上等待时间最长的顾客理发,同时空出的沙发让在等候室中等待时间最长的的顾客就坐。

顾客理完发后,可向任何一位理发师付款。

但理发店只有一本现金登记册,在任一时刻只能记录一个顾客的付款。

理发师在没有顾客的时候就坐在理发椅子上睡眠。

理发师的时间就用在理发、收款、睡眠上。

请利用linux系统提供的IPC进程通信机制实验并实现理发店问题的一个解法。

实验目的:进一步研究和实践操作系统中关于并发进程同步与互斥操作的一些经典问题的解法,加深对于非对称性互斥问题有关概念的理解。

观察和体验非对称性互斥问题的并发控制方法。

进一步了解Linux系统中IPC进程同步工具的用法,训练解决对该类问题的实际编程、调试和分析问题的能力。

硬件环境:Inter(R)Core(TM)i5-3210M CPU @ 2.50GHz 内存:4GB 硬盘:500G软件环境:XUbuntu-Linux 操作系统Gnome 桌面 2.18.3BASH_VERSION='3.2.33(1)-releasegcc version 4.1.2gedit 2.18.2OpenOffice 2.3实验步骤:1、问题分析:为了解决本实验的同步问题,采用共享内存,信号量,消息队列三种IPC 同步对象处理。

客户程序思想:每一个客户把自己的请求当做一条消息发送到相应的消息队列中去,并通过阻塞等待接收消息的方式来等待理发师最终帮自己理发。

每一个客户先判断sofa 是不是坐满了,如果没有就坐在沙发上等,否者就判断waitroom 是不是坐满了,如果没有,就坐在waitroom 等,只要有一个坐在sofa的客户离开sofa 理发,理发师就会到waitroom 找最先来的客户,让他进入sofa 等待。

操作系统实验报告barber实验

操作系统实验报告barber实验

操作系统实验报告barber实验操作系统实验报告:Barber 实验一、实验目的本次实验的主要目的是通过模拟理发店中理发师和顾客的行为,深入理解操作系统中的进程同步与互斥机制。

通过实际编程实现,观察和分析不同情况下进程的执行顺序和资源的分配情况,从而更好地掌握操作系统中对于并发控制的原理和方法。

二、实验环境本次实验使用的编程语言为 Python,开发环境为 PyCharm。

操作系统为 Windows 10。

三、实验原理理发店问题是一个经典的进程同步问题。

假设有一个理发店,店内有一个理发师和 n 把椅子供顾客等待。

如果没有顾客,理发师就会去睡觉;如果有顾客到来且有空椅子,顾客就会坐下等待;如果没有空椅子,顾客就会离开。

当理发师正在为一个顾客理发时,其他顾客需要等待。

当理发师完成当前顾客的理发后,会从等待的顾客中选择一位继续服务。

为了实现这个问题的模拟,我们需要使用信号量来控制进程的同步和互斥。

信号量是一种用于解决进程同步和互斥问题的工具,它可以实现对共享资源的访问控制。

四、实验代码实现```pythonimport threadingimport time定义信号量mutex = threadingSemaphore(1) 用于互斥访问椅子数量customers = threadingSemaphore(0) 顾客数量barber_ready = threadingSemaphore(0) 理发师准备好的信号量椅子数量n = 5顾客线程函数def customer():global nwhile True:timesleep(1) 顾客随机到达if n > 0:n = 1print(f"顾客进入理发店,还有{n}个空椅子")customersrelease()mutexrelease()barber_readyacquire()print("顾客开始理发")else:print("理发店已满,顾客离开")mutexrelease()理发师线程函数def barber():while True:customersacquire()mutexacquire()n += 1print("理发师为顾客理发,还有{n}个空椅子")barber_readyrelease()timesleep(3) 理发时间print("理发完成")创建顾客线程customer_threads = threadingThread(target=customer) for _ in range(10)创建理发师线程barber_thread = threadingThread(target=barber)启动线程barber_threadstart()for thread in customer_threads:threadstart()等待线程结束barber_threadjoin()for thread in customer_threads:threadjoin()```五、实验结果与分析在实验运行过程中,我们观察到以下几种情况:1、当有顾客随机到达且店内有空椅子时,顾客会进入店内等待,并通知理发师。

计算机操作系统理发师问题-JAVA

计算机操作系统理发师问题-JAVA

课程实验报告题目计算机操作系统理发师问题姓名潘 *学号 2013 ***年级专业2013级*指导教师彭 * 华201*年1*月 30 日一题目假设有个理发店,只有一个理发师和N张可供顾客等待理发的椅子,如果没有顾客,则理发师睡觉,如果有一个顾客进入理发店发现理发师在睡觉,则把他叫醒,试用信号量设计一个协调理发师和顾客的程序。

二 PV操作伪代码C语言的伪代码实现:int waiting=0 ;//等候理发的顾客数int chairs=n;//为顾客准备的椅子数semaphore customers=0, barbers=0,mutex=1;barber() {while(TRUE); //理完一人,还有顾客吗?P(cutomers); //若无顾客,理发师睡眠P(mutex); //进程互斥waiting -= 1;//等候顾客数少一个V(barbers); //理发师去为一个顾客理发V(mutex); //开放临界区cut-hair(); //正在理发}customer() {P(mutex); //进程互斥if(waiting) {waiting += 1; // 等候顾客数加1V(customers); //必要的话唤醒理发师V(mutex); //开放临界区P(barbers); //无理发师, 顾客坐着养神get-haircut( ); //一个顾客坐下等理/}else V(mutex); //人满了,离开}三程序流程图顾客模块:理发师模块:四源程序的实现因为本人对C++的多线程库函数不了解,于是使用JAVA实现理发师问题,假设有5张可供顾客理发的椅子:package com.swxy;import java.util.concurrent.Semaphore;//导入Semaphore,用于控制进程同步互斥的量。

public class BarberShop {static int cnt = 0;// 顾客static int MAX = 5;// 假设5张可供顾客理发的椅子static int busy = 0;static Semaphore mutex= new Semaphore(1);// 临界区互斥访问信号量(二进制信号量),相当于互斥锁。

《操作系统》打瞌睡理发师课程设计

《操作系统》打瞌睡理发师课程设计

课程设计(论文)课程名称______操作系统___________题目名称_____打瞌睡理发师问题______学生学部(系)___信息与计算机学部__专业班级_08计算机科学与技术3班____学号____ ____________学生姓名________ _____________指导教师________ _ ___________ 2010 年 12 月 28 日课程设计(论文)任务书一、课程设计(论文)的内容模拟解决打瞌睡的理发师问题:理发店内有一名理发师,一把理发椅,和N把普通的椅子。

如果没有顾客来,那么理发师就坐在理发椅上打瞌睡;当顾客到来时,就唤醒理发师。

如果顾客到来时理发师正在理发,顾客就坐下来等待。

如果N把椅子都坐满了,顾客就离开该理发店到别处去理发。

理发师刚开始理发时,先看看店里有没有顾客,如果没有,则在理发椅上打瞌睡;如果有顾客,则为等待时间最长的顾客理发,且等待人数减1。

顾客来到店里,先看看有无空位,如果没有空位,就不等了。

离开理发店;如果有空位则等待,等待人数加1;如果理发师在打瞌睡,则将其唤醒。

二、课程设计(论文)的要求与数据(1)需求分析(2)系统设计(3)模块代码能正常运行(4)提供合理的测试数据(5)设计说明文档三、课程设计(论文)应完成的工作(1)采用模块化的程序设计方法,程序书写符合规范,代码应完善。

(2)要有运行结果和过程的界面截图。

(3)对系统进行初步的错误和漏洞检测;(4)根据论文规范撰写论文,用A4纸打印并按时提交。

四、课程设计(论文)进程安排五、应收集的资料及主要参考文献[1] 郁红英,李春强.计算机操作系统.北京:清华大学出版社,2008[2] 孟庆昌.操作系统.北京:电子工业出版社,2009[3] 汤子瀛,哲凤屏.计算机操作系统.北京:电子工业出版社,2009[4] 尤晋元,史美林等.windows操作系统原理.北京:机械工业出版社,2001[5] 孟静.计算机操作系统原理教程.北京:清华大学出版社,2005[6] 广树建.新编C/C++程序设计教程.广州:华南理工出版社,2008发出任务书日期: 2010 年 12 月 10 日指导教师签名:计划完成日期: 2011 年 1 月 5 日通过对《操作系统》这门课的学习后,要求我们能够在深刻理解和应用有关经典进程的同步和互斥问题之余,能够模拟解决打瞌睡的理发师问题。

操作系统课程设计---理发师问题的实现

操作系统课程设计---理发师问题的实现

操作系统课程设计---理发师问题的实现(总18页)本页仅作为文档封面,使用时可以删除This document is for reference only-rar21year.March*******************实践教学*******************兰州理工大学计算机与通信学院2011年秋季学期操作系统课程设计题目:理发师问题的实现专业班级:计算机科学与技术姓名:学号:指导教师:成绩:摘要理发师问题是一个利用信号量进行PV操作的经典问题。

设计程序实现此问题,要使得理发师的活动与顾客的活动得到各自真实的模拟。

所执行的程序应体现:理发师在没有顾客的时候去睡觉,有顾客则工作;顾客在理发师工作时坐下等待,无座时离开,直至等到理发师自己理发。

关键字:理发师,顾客,PV操作。

目录摘要................................................................................................................. 错误!未定义书签。

1 设计要求........................................................................................................ 错误!未定义书签。

初始条件 ........................................................................................ 错误!未定义书签。

技术要求 ........................................................................................ 错误!未定义书签。

2 总体设计思想及开发环境与工具................................................................ 错误!未定义书签。

操作系统练习 同步问题 有答案

操作系统练习 同步问题 有答案

操作系统练习题:1 在南开大学和天津大学之间有一条弯曲的小路,其中从S到T一段路每次只允许一辆自行车通过,但中间有一个小的“安全岛”M(同时允许两辆自行车停留),可供两辆自行车已从两端进小路情况下错车使用,如图所示。

试设计一个算法使来往的自行车均可顺利通过。

解答:首先中间的安全岛M仅允许两辆自行车通过,应作为临界资源设置信号量。

但仔细分析发现,在任何时刻进入小路的自行车最多不会超过两辆(南开和天大方向各一辆),因此不需为安全岛M设置信号量。

在路口S处,南开出发的若干辆自行车应进行路口资源的争夺,以决定谁先进入小路SK段,为此设置信号量S,用以控制路口资源的争夺;同理,设置信号量T,控制天大方向自行车对路口T的争夺。

又小路SK段仅允许一辆车通过,设置信号量SK初值为1,同理设置小路LT段信号量LT初值为1。

程序如下:S := l; T:=1; SK :=1; LT:=1;Parbegin进程P:(南开方向自行车)beginP(S) ; {与其它同方向的自行车争夺路口S}P(SK); {同对面自行车争夺路段SK}通过SK;进入M;**V (SK);{一旦进入M,便可释放路段SK}P (LT) ; {同对面的自行车争夺路段LT}通过LT;V (LT);{将路段LT释放}V(S); {将路口S释放给同方向的正在路口S处等待的自行车}end,进程Q:(天大方向自行车)beginP(T);P(LT);通过LT;进入M;V(LT);P(SK);通过SK;V(SK);V(T);End;Parend。

说明**:P进程进入安全岛M后,释放了路段SK,但没有释放路口S,原因在于它是向对面的4进程释放路段资源SK,而在P进程离开小路LT后,才会将路口S 释放给其他P进程,如不这样,就会死锁。

请考虑如下情况:两个方向各有一辆车前进,若在P进程到达安全岛M后,执行V (S)及V (SK)操作,则有可能使得同方向的其它P进程得到路段SK的使用权,而进入小路;同理,Q进程到达安全岛后执行V (LT)及V (T)操作,有可能使得同方向的其它Q进程得到路段LT 而进入小路。

理发师问题操作系统课程设计

理发师问题操作系统课程设计

理发师问题操作系统课程设计河南城建学院《操作系统》课程设计报告课程名称: 《操作系统》课程设计设计题目: 理发师问题指导教师: 李蓓耿永军班级:学号:学生姓名:同组人员:成绩:评语:计算机科学与工程学院2014年6月19日前言现在计算机更新如此迅速的时代要学好计算机软件技术,特别是操作系统的学习,不仅要努力学好课本上的基础知识,还要经常在图书馆看些有关这方面的书籍,而更重要的是要有足够的实践经验,也要注重和同学的交流,经常尝试性的做些小的操作系统,对自己技术的提升会有很大的帮助。

同时,学习计算机操作系统技术,除了需要刻苦努力外,还需要掌握软件和操作系统的原理与设计技巧。

如何学习和掌握操作系统技术的原理与实际技巧呢?除了听课和读书之外,最好的方法恐怕就是在实践中练习。

例如,自己设计一个小型操作系统,多使用操作系统,多阅读和分析操作源代码等。

但由于我们的条件和学时有限,在理论学习过程中没有给同学们提供更多的实验机会。

本操作系统课程设计,是给同学提供一个集中实验的机会。

希望同学们通过该设计加深对所学习课程的理解。

本设计的内容是基于《操作系统原理》、《C语言程序设计》和《数据结构》等内容。

本设计是基于课程中学到的UNIX系统调用,使用操作系统环境是Red Hat Linux 9,言语开发环境是Linux的GNU C或C++。

完成本次课程设计,首先必须配置操作系统编写的所需的环境,包括虚拟机的建立和相应环境建立。

用VI编辑器编写相应得程序,以实现理发师进程的同步与互斥。

目录第一章.系统环境 ..................................................................... .. (1)1.1硬件环境 ..................................................................... . (1)1.2软件环境 ..................................................................... . (1)第二章.设计目的及要求 ..................................................................... .. (2)2.1设计目的 ..................................................................... . (2)2.2 要求 ..................................................................... .. (2)2.3 内容 ..................................................................... .. (2)第三章.总体设计 ..................................................................... .. (3)3.1程序设计组成框图 ..................................................................... (3)3.2 主函数流程图 ..................................................................... . (4)3.3理发师进程流程图 ..................................................................... (5)3.4 顾客进程流程图 ..................................................................... (5)3.5函数调用 ..................................................................... . (6)第四章.详细设计 ..................................................................... .. (7)4.1概要设计 ..................................................................... . (7)4.1.1 数据结构 ..................................................................... .. (7)4.1.2 多线程编译原理 ..................................................................... .. (7)4.1.3 创建线程 ..................................................................... .. (7)4.1.4 信号量 ..................................................................... (8)4.2 头文件声明 ..................................................................... .. (8)4.3函数定义 ..................................................................... . (9)4.4 变量定义 ..................................................................... (9)4.5函数实现 ..................................................................... . (9)第五章.调试与测试 ..................................................................... .. (11)5.1调试方法 ..................................................................... .. (11)5.2结果分析 ..................................................................... ..................................................... 13 第六章.设计中遇到的问题及解决方法 ..................................................................... (14)6.1出现的问题 ..................................................................... . (14)6.2解决方法 ..................................................................... ..................................................... 14 第七章.源程序清单和执行结果 ..................................................................... (16)7.1源程序清单 ..................................................................... . (16)7.2程序执行结果 ..................................................................... ............................................. 19 第八章.心得体会 ..................................................................... (20)第九章.参考文献 ..................................................................... (21)1 《操作系统》课程设计第一章.系统环境1.1硬件环境内存1GB,处理器1,硬盘(SCSI)50GB,网络适配器NAT。

操作系统--理发师问题

操作系统--理发师问题

操作系统--理发师问题正文:一:背景介绍理发师问题是一个经典的并发编程问题,涉及到同时访问共享资源的多个线程之间的同步问题。

该问题的背景可以描述为:在一个理发店里,有一个理发师和一排等待理发的顾客,每个顾客需要等待一段时间才能坐到理发椅上理发。

当有空闲的理发师时,顾客就会坐到椅子上进行理发,否则就需要等待其他顾客理发结束。

该问题需要设计一个合理的算法,保证每个顾客都能够得到理发椅上的理发服务。

二:问题分析1. 线程模型与同步机制考虑到理发师问题涉及到多个顾客同时访问共享资源(理发椅)的情况,可以使用线程模型来解决该问题。

其中,每个顾客作为一个线程,理发椅作为共享资源。

在本问题中,通过使用信号量进行同步机制的设计,保证每个顾客能够按顺序得到理发师的服务。

2. 线程同步的三个要素在解决理发师问题时,需要考虑线程同步的三个要素:互斥、有序性和死锁避免。

互斥可以通过互斥量来实现,保证只有一个线程同时访问共享资源;有序性可以通过信号量来控制,保证顾客能够按照先来后到的顺序进行理发;死锁避免可以通过设置超时等待时间来解决。

三:算法设计1. 初始条件设置首先,需要确定理发师数量、理发椅数量和顾客数量的初始设置。

可以通过命令行参数或配置文件进行设置,以适应不同场景的需求。

2. 创建线程根据顾客数量创建对应数量的线程,并将每个顾客线程的任务设置为等待理发的状态。

同时,创建理发师线程,并将理发师的任务设置为等待顾客的状态。

3. 理发师任务理发师从等待队列中取出一个顾客进行理发,理发时间可以通过随机数。

当该顾客理发结束后,理发师继续从等待队列中取出下一个顾客进行理发。

如果没有顾客在等待,则理发师进入休息状态。

4. 顾客任务顾客到达理发店后,首先判断是否有空闲的理发椅。

如果有空闲的椅子,则顾客坐下并进行理发;否则,顾客需要等待其他顾客离开理发椅后才能进行理发。

5. 同步机制使用互斥量保证理发师和顾客对共享资源的互斥访问。

理发师问题

理发师问题

Linux系统分析实验报告用信号量解决理发师问题061261008 蒋炎岩(一班)1 实验要求理发师问题:理发店理有一位理发师、一把理发椅和5把供等候理发的顾客坐的椅子。

如果没有顾客,理发师便在理发椅上睡觉一个顾客到来时,它必须叫醒理发师,如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。

用Linux线程机制和信号量机制解决这个问题,并且:(1)每个顾客进入理发室后,即时显示“Entered”及其线程标识,还同时显示理发室共有几名顾客及其所坐的位置(2)至少有10个顾客,每人理发至少3秒钟。

(3)多个顾客须共享操作函数代码。

2 背景知识2.1 POSIX线程在一个程序中的多个执行路线称之为线程。

Linux在1996年第一次获得线程支持,现在已经有一套完整的与线程有关的函数库调用,大多数以pthread_开头,编译时需要用-lpthread选项进行连接。

我们用函数pthread_create创建一个新线程:#include <pthread.h>int pthread_create(pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg);thread参数表示新线程的标识符;attr用于设置线程属性,如不需要设置,可设置为NULL;start_routine标识了线程启动程序的入口,arg为传入的参数。

调用pthread_create 就可以立即创建一个新的执行路线,与原有线程共享所有的主存空间,但拥有独立的堆栈。

2.2 信号量信号量通过一个计数器控制对共享资源的访问。

如果计数器大于0,则访问被允许,如果为0,则访问被禁止。

计数器计算的结果是允许访问共享资源的通行证。

因此,为了访问共享资源,线程必须从信号量得到通行证(P操作),如果该信号量的计数大于0,则此线程获得一个通行证,这将导致信号量的计数递减,否则,此线程将阻塞直到获得一个通行证为止。

理发师问题——《操作系统》课程设计报告 (1)

理发师问题——《操作系统》课程设计报告 (1)

课程设计报告课程名称操作系统课题名称嗜睡的理发师问题专业信息管理与信息系统班级学号姓名指导教师2016 年 6 月18 日湖南工程学院课程设计任务书课程名称操作系统课题嗜睡的理发师问题专业班级信管1301学生姓名学号指导老师审批任务书下达日期2016 年 6 月 3 日任务完成日期2016 年 6 月17 日一、设计内容与设计要求1.课程设计目的:《操作系统》课程设计是信管专业实践性环节之一,是学习完《操作系统》课程后进行的一次较全面的综合练习。

其目的在于加深对操作系统的理论、方法和基础知识的理解,掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力,并了解操作系统的发展动向和趋势。

进一步提高上机动手能力,培养使用计算机解决实际问题的能力,为后继课程的学习和实验,以及毕业设计的完成打下扎实的基础。

2.课题题目嗜睡的理发师问题一个理发店由一个有N张沙发的等候室和一个放有一张理发椅的理发室组成。

没有顾客要理发时,理发师便去睡觉。

当一个顾客走进理发店时,如果所有的沙发都已被占用,他便离开理发店;否则,如果理发师正在为其他顾客理发,则该顾客就找一张空沙发坐下等待;如果理发师因无顾客正在睡觉,则由新到的顾客唤醒理发师为其理发。

在理发完成后,顾客必须付费,直到理发师收费后才能离开理发店。

试用信号量实现这一同步问题。

3.设计要求:1.根据自己对应的课题完成以下主要工作:(1).分析设计要求,给出解决方案,建立必要的数据结构,然后设计总体流程(包括界面)、详细设计必要的算法,并最终显示结果。

基于WINDOWS或LINUX操作系统都可以,用何种编程语言都有可以。

(2).提交设计报告,包括设计要求、设计思想流程、设计所涉及的主要数据结构、程序清单、运行结果、设计心得、参考资料等。

(3).严禁抄袭,复制设计内容,查出后相关同学设计成绩以零分处理。

(4).所提交源程序应是能够运行通过的完整程序。

操作系统--理发师问题

操作系统--理发师问题

设计思想的说明:打瞌睡的理发师问题是一种同步问题的抽象描述。

计算机系统中的每个进程都可以消费或生产某类资源,当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。

而当某个进程释放资源时,则它就相当一个生产者。

因此此题可看作是n个生产者和1个消费者问题。

顾客作为生产者,每到来一个就使计数器count增加1,以便让理发师理发(相当于消费)至最后一个顾客(相当于产品)。

并且,第1个到来的顾客应负责唤醒理发师;如果不是第1个到达的顾客,则在有空椅子的情况下坐下等待,否则离开理发店(该消息可由计数器count获得),所以可以通过一个有界缓冲区把理发师和顾客联系起来通过对信号进行P、V操作来实现有关问题和相关描述。

源程序文件:#include<windows.h>#include<stdio.h>#include<iostream>#include<process.h>#include<conio.h>#include<ctime>using namespace std;#define CHAIRS 3 //椅子的个数#define BARBERS 1 //理发师的个数#define CUSTOMESTOCOME 7 //将要来的顾客的数目typedef HANDLE semaphore;static int count=0; //记录理发店顾客的总数,初始化为0int leaved=0; //记录理发店顾客的总数,初始化为0int waiting=0;time_t endtime; //关闭营业的时间//coustomers初始化为0,最大顾客数为3semaphore customers=CreateSemaphore(NULL,0,CHAIRS,TEXT("customers")); //barbers的数量初始化为1,假设一共有1个barbersemaphorebarbers=CreateSemaphore(NULL,BARBERS,BARBERS,TEXT("barbers"));//建立互斥变量,用于保护共享资源HANDLE mutex=CreateMutex(NULL,FALSE,TEXT("mutex"));DWORD WINAPI barber(LPVOID lparameter);DWORD WINAPI customer(LPVOID lparameter);//理发师理发void cutHair();//顾客坐到椅子上等待void getChair();//等待顾客到来void wait();//顾客离开void customerLeave();//顾客进入void customerEnter();void up(HANDLE hHandle){//对指定信号量增加指定的值ReleaseSemaphore(hHandle,1,NULL);//恢复线程ResumeThread(hHandle);}void upMutex(HANDLE hMutex){//释放线程拥有的互斥体ReleaseMutex(hMutex);}void down(HANDLE hHandle){ //DOWN operation//线程挂起,等待信号WaitForSingleObject(hHandle,INFINITE);}int main(){//结束时间endtime=time(0)+20000;//创建理发师线程HANDLE barberThread=CreateThread(NULL,0,barber,NULL,0,NULL);HANDLE customerThread;//产生10个客户进程,每两个进程之间间隔一个随见时间1000~1050 while(count<CUSTOMESTOCOME){//创建客户进程customerThread=CreateThread(NULL,0,customer,NULL,0,NULL);srand(unsigned(time(0)));int time=rand()%1000+50;Sleep(time);}//释放资源CloseHandle(barberThread);CloseHandle(customerThread);CloseHandle(barbers);CloseHandle(customers);CloseHandle(mutex);cout<<"离开的顾客总数为:"<<leaved<<endl;return 0;}DWORD WINAPI barber(LPVOID lparameter) {while(time(0)<endtime){//没有客户,则进入睡眠状态down(customers);//临界区操作down(mutex);waiting=waiting-1;upMutex(mutex);//开始理发cutHair();//理发结束,理发师信号量加1up(barbers);}return 0;}DWORD WINAPI customer(LPVOID lparameter){ //客户到来customerEnter();//临界区操作down(mutex);cout<<"等̨¨待äy的Ì?顾?客¨ª数ºy: "<<waiting<<endl;cout<<"空?椅°?子Á¨®数ºy: "<<CHAIRS-waiting<<endl;if(waiting<CHAIRS){ //如果有空椅子,客户等待,否则离开if(waiting!=0){//等待顾客到来wait();}waiting=waiting+1;//客户信号量加1up(customers);upMutex(mutex);//离开临界区//理发师进程等待唤醒down(barbers);//顾客坐下来等待getChair();}else{//释放互斥锁upMutex(mutex);//顾客离开customerLeave();}return 0;}void cutHair(){static int served=0;served++;cout<<理发师帮第"<<served<<"位被服务的顾客理发"<<endl;Sleep(1000);cout<<"第"<<served<<"位被服务的顾客理完发"<<endl;}void getChair(){Sleep(1050);}void customerEnter(){count++;SYSTEMTIME sys;GetLocalTime( &sys );cout<<endl<<"第"<<count<<"位顾客进来"<<endl;}void wait(){cout<<"有空位,第"<<count<<"位顾客就坐"<<endl;}void customerLeave(){cout<<"没有空椅子,第"<<count<<"位顾客离开 ."<<endl;leaved++;}输出截图:PS:由于我对c++中处理进程、信号的函数不熟,所以有许多参考了网上的代码。

系统调用中的信号量PV操作 理发师问题

系统调用中的信号量PV操作 理发师问题

⏹理发师问题:一个理发店由一间等候室W和一间工作室B组成。

顾客可以从外面大街上进入W等候理发。

两个房间的入口是并排的,且共享一扇日本式可滑动的推拉门(门总是挡住一个入口)。

顾客在工作室内理完发,可由B 的旁门出去。

W中有N把椅子,顾客必须坐着等候。

理发师可由门上小窗查看W中无人就睡觉,否则开门,并叫一位顾客入内理发。

顾客每进入一位,都拉铃通知理发师。

若把顾客和理发师都视为进程,请用P、V操作写出进程的同步算法。

⏹要求打印:题目中要求描述理发师和顾客的行为,因此需要两类线程barber()和customer ()分别描述理发师和顾客的行为。

其中,理发师有活动有理发和睡觉两个事件;等待和理发二个事件。

店里有固定的椅子数,上面坐着等待的顾客,顾客在到来这个事件时,需判断有没有空闲的椅子,理发师决定要理发或睡觉时,也要判断椅子上有没有顾客。

所以,顾客和理发师之间的关系表现为:(1)理发师和顾客之间同步关系:当理发师睡觉时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师睡觉。

(2)理发师和顾客之间互斥关系:由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n把,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。

(3)故引入3个信号量和一个控制变量:ⅰ控制变量waiting用来记录等候理发的顾客数,初值为0;ⅱ信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;ⅲ信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为1;ⅳ信号量mutex用于互斥,初值为1using System;using System.Collections.Generic;using System.Text;using System.Threading;namespace理发师问题2{internal class Program{// Fieldsprivate static Semaphore barbers = new Semaphore(1, 10);private static int chairs;private static int count = 0;private static Semaphore customers = new Semaphore(0, 10);private static int finish = 0;private static Semaphore mtx = new Semaphore(1, 10);private static int waiting = 0;// Methodspublic static void barber(){while (true){customers.WaitOne();mtx.WaitOne();waiting--;barbers.Release();mtx.Release();cuthair();finish++;}}public static void customer(){mtx.WaitOne();count++;Console.WriteLine("叮咚!第{0}个顾客来了", count);if (waiting < chairs){if (waiting > 0){Console.WriteLine("此时有{0}个人在等待理发", waiting);}else{Console.WriteLine("没有人在等待");}waiting++;Console.WriteLine("还有{0}个座位,顾客留下", (chairs - waiting) + 1);mtx.Release();customers.Release();barbers.WaitOne();gethaircut();}else{Console.WriteLine("座位已满,第{0}个顾客离开", count); mtx.Release();}}public static void cuthair(){Console.WriteLine("开始理发!这是理发师的第{0}个顾客.", finish + 1);Thread.Sleep(0x2328);Console.WriteLine("理发完成 !");}public static void gethaircut(){Thread.Sleep(0x238c);Console.WriteLine("第{0}个顾客理发完毕,离开.", finish);}private static void Main(string[] args){string str = string.Empty;Console.WriteLine("请输入椅子的总数目:");chairs = Convert.ToInt32(Console.ReadLine());Console.WriteLine("理发店共有{0}把椅子", chairs);Console.WriteLine("开门接待顾客吗?Y/N");for(string str2 = Console.ReadLine(); (str2 != "Y") && (str2 != "y"); str2 = Console.ReadLine()){Console.WriteLine("********对不起,尚未开门!********");Console.WriteLine("开门接待顾客吗?Y/N");}Console.WriteLine("********营业中,欢迎光临!********");new Thread(new ThreadStart(Program.barber)).Start();while ((str != "y") && (str != "Y")){Random random = new Random(lisecond);Thread.Sleep(random.Next(1, 0x2710));Console.WriteLine("*******************************");new Thread(new ThreadStart(Program.customer)).Start();if ((finish >= 10) && (waiting == 0)){Console.WriteLine("已经为{0}个顾客理发了,要关门下班吗?(Y/N)", finish);str = Console.ReadLine();}if ((str == "Y") || (str == "y")){Console.WriteLine("************暂停营业!**********");break;}}}}}题目: 用多线程同步方法解决睡眠理发师问题(Sleeping-Barber Problem)理发店有一位理发师,一把理发椅和n把用来等候理发的椅子。

同步与互斥实例

同步与互斥实例
(1)进程A专门拣黑子,进程B专门拣白子;
(2)每个进程每次只拣一个子,当一个进程在 拣子时不允许另一进程去拣子;
(3)当一个进程拣了一个子(黑或白)以后, 必让另一个进程拣一个子(黑或白) 。
请用P、V操作管理两个并发进程,使其能正 确实现上述功能。
Var S1, S2: semaphore:=1,0;
理发师问题理发师问题l理发店里有一位理发师一把理发椅和n把供等候理发的顾客坐的椅子l如果没有顾客理发师便在理发椅上睡觉l一个顾客到来时它必须叫醒理发师l如果理发师
进程同步与互斥实例
同步实例
1.经典的生产者─消费者问题
生产者
消费者
1.经典的生产者─消费者问题
var B : integer;
empty:semaphore; /* 可以使用的空缓冲区数 */
process 小和尚: begin repeat P(empty); P(count); P(mutex1); 从井中取水; V(mutex1); P(mutex2); 送水入水缸; V(mutex2); V(count); V(full); until false;
end
Var mutex1, mutex2, empty, full, count: semaphore;
④在每个进程中用于实现互斥的PV操作必须成对出现;用于实现 同步的PV操作也必须成对出现,但可以分别出现在不同的进程中; 在某个进程中如果同时存在互斥与同步的P操作,则其顺序不能颠 倒,必须先执行对同步信号量的P操作,再执行对互斥信号量的P 操作,但V操作的顺序没有严格要求。
同步与互斥的解题步骤
full:semaphore;
/* 缓冲区内可以使用的产品数 */
empty := 1;

操作系统算法复习题以及各题标准答案

操作系统算法复习题以及各题标准答案

操作系统算法各题标准答案真经之理发师问题扩展(电子科技大学2000)有一个理发师,一把理发椅和n把供等候理发的顾客坐的椅子,若没有顾客,则理发师睡觉,当一个顾客到来时,必须唤醒理发师进行理发, 若理发师正在理发,又有顾客到来,则若有空椅子可坐就坐下来等,若没有空椅子就离开.问题分析:需要设置一个信号量barber,初值为0,用于控制理发师和顾客之间的同步关系.还需要设置一个信号量customer,初值为0,用于离开顾客与等候顾客之间的同步控制,为了记录等候的顾客数, 应该设置一个计数器count,初值为0.当一个顾客到达时,需要在count上做加1操作,并根据count值的不同分别采取不同的动作,当顾客离开时,要对count上做减1操作,并根据count值的不同分别采取不同的动作;由于count是共享变量,因此要互斥使用,为此设置一个互斥信号量mutex;beginvarbarber=0,customer=0,count=0,mutex=1:s emaphore;cobeginprocess barberbeginrepeatp(customer);p(mutex);count = count -1;v(barber);v(mutex);理发;until falseEndprocess customer beginrepeat;p(mutex);if(count<n){count = count +1;v(customer);p(barber);理发;}else{v(mutex);离开;}until falseendcoendEnd真经之生产消费问题扩展(浙江大学2001) 假设缓冲区buf1和缓冲区buf2无限大,进程p1向buf1写数据,进程p2向buf2写数据,要求buf1数据个数和buf2数据个数的差保持在(m,n)之间(m<n,m,n都是正数).问题分析:题中没有给出两个进程执行顺序之间的制约关系,只给出了一个数量上的制约关系,即m·—buf1数据个数-buf2数据个数·n.不需要考虑缓冲区的大小,只需要考虑两个进程的同步和互斥.p2向buf2写数据比p1向buf1写数据的次数最少不超过m次,最多不能超过n次,反之也成立.所以是一个生产者和消费者问题。

理发店问题

理发店问题
七、附录(源程序)
#include <windows.h> #include "iostream.h" #include "math.h"
#define random (rand()*10000)/RAND_MAX //定义一个随机函数来产生顾客,并且使两个顾客间的时间少于10秒
int long waiting(0); //正在等待的顾客的数目
} void gethaircut() { Sleep (10001); //顾客被理发的函数,为了和理发师之间有所区别,比理发师理发时间长0.001秒 。 cout<<"第"<<finish<<"个顾客理发完毕,离开 "<<endl; } HANDLE Mutex=CreateMutex(NULL, FALSE, "Mutex"); //用来实现进程的互斥 HANDLE barbers=CreateSemaphore(NULL, 1,1, "barbers");//定义信号量来进行线程间的同步 HANDLE customers=CreateSemaphore(NULL,0,3,"customers");
2、涉及的数据结构
程序中引入3个信号量和一个控制变量:
(1)控制变量wait用来记录等候理发的顾客数,初值均为0; (2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程 ,初值为0; (3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程
,初值为1;
(4)信号量Mutex用于互斥,初值1. int long wait(0); /*正在等待的顾客的数目 */ int sofas; /*为顾客准备的椅子数*/ customers, barbers,mutex : semaphore; customers = 0; barbers = 1; wait = 0; mutex = 1;

计算机操作系统理发师问题-JAVA模板

计算机操作系统理发师问题-JAVA模板

课程实验报告题目计算机操作系统理发师问题姓名潘 *学号 2013 ***年级专业2013级*指导教师彭 * 华201*年1*月 30 日一题目假设有个理发店,只有一个理发师和N张可供顾客等待理发的椅子,如果没有顾客,则理发师睡觉,如果有一个顾客进入理发店发现理发师在睡觉,则把他叫醒,试用信号量设计一个协调理发师和顾客的程序。

二 PV操作伪代码C语言的伪代码实现:int waiting=0 ;//等候理发的顾客数int chairs=n;//为顾客准备的椅子数semaphore customers=0, barbers=0,mutex=1;barber() {while(TRUE); //理完一人,还有顾客吗?P(cutomers); //若无顾客,理发师睡眠P(mutex); //进程互斥waiting -= 1;//等候顾客数少一个V(barbers); //理发师去为一个顾客理发V(mutex); //开放临界区cut-hair(); //正在理发}customer() {P(mutex); //进程互斥if(waiting) {waiting += 1; // 等候顾客数加1V(customers); //必要的话唤醒理发师V(mutex); //开放临界区P(barbers); //无理发师, 顾客坐着养神get-haircut( ); //一个顾客坐下等理/}else V(mutex); //人满了,离开}三程序流程图顾客模块:理发师模块:四源程序的实现因为本人对C++的多线程库函数不了解,于是使用JAVA实现理发师问题,假设有5张可供顾客理发的椅子:package com.swxy;import java.util.concurrent.Semaphore;//导入Semaphore,用于控制进程同步互斥的量。

public class BarberShop {static int cnt = 0;// 顾客static int MAX = 5;// 假设5张可供顾客理发的椅子static int busy = 0;static Semaphore mutex= new Semaphore(1);// 临界区互斥访问信号量(二进制信号量),相当于互斥锁。

理发师问题

理发师问题

理发师问题理发师问题:一个理发店有一个入口和一个出口。

理发店内有一个可站5 位顾客的站席区、4 个单人沙发、3 个理发师及其专用理发工具、一个收银台。

新来的顾客坐在沙发上等待;没有空沙发时,可在站席区等待;站席区满时,只能在入口外等待。

理发师可从事理发、收银和休息三种活动。

理发店的活动满足下列条件:1)休息的理发师是坐地自己专用的理发椅上,不会占用顾客的沙发;2)处理休息状态的理发师可为在沙发上等待时间最长的顾客理发;3)理发时间长短由理发师决定;4)在站席区等待时间最长的顾客可坐到空闲的理发上;5)任何时刻最多只能有一个理发师在收银。

试用信号量机制或管程机制实现理发师进程和顾客进程。

原理:(1)customer 进程:首先检查站席区是否已满(stand_capacity),若满选择离开,否则进入站席区,即进入理发店。

在站席区等待沙发的空位(信号量sofa),如果沙发已满,则进入阻塞等待队列,直到出现空位,在站席区中等待时间最长的顾客离开站席区(stand_capacity)。

坐到沙发上,等待理发椅(barber_chair),如果理发椅已满,则进入阻塞等待队列,直到出现空位,在沙发上等待时间最长的顾客离开沙发(释放信号量sofa)。

坐到理发椅上,释放准备好的信号(customer_ready),获得该理发师的编号(0~1 的数字)。

等待理发师理发结束(finished[barber_number])。

在离开理发椅之前付款(payment),等待收据(receipt),离开理发椅(leave_barberchair)。

最后离开理发店。

这里需要注意几点:a) 首先是几个需要进行互斥处理的地方,主要包括:进入站席区、进入沙发、进入理发椅和付款几个地方。

b) 通过barber_chair 保证一个理发椅上最多只有一名顾客。

但这也不够,因为单凭baber_chair 无法保证一名顾客离开理发椅之前,另一位顾客不会坐到该理发椅上,因此增加信号量leave_barberchair,让顾客离开理发椅后,释放该信号,而理发师接收到该信号后才释放barber_chair 等待下一位顾客。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验题目:理发师问问题学号:201000130133 班级: 2010级计算机4班姓名:郑思雨 Email:1412561943@实验目的:1、进一步研究和实践操作系统中关于并发进程同步与互斥操作的一些经典问题的解法。

2、加深对于非对称性互斥问题有关概念的理解。

观察和体验非对称性互斥问题的并发控制方法。

3、进一步了解Linux系统中IPC进程同步工具的用法,训练解决对该类问题的实际编程、调试和分析问题的能力。

硬件环境:微机(多核,4GB 以上内存,320GB 以上硬盘)软件环境:Ubuntu-Linux 操作系统Gnome 桌面gcc version 4.1.2gedit 2.18.2OpenOffice 2.3实验步骤:1、了解实验的目的,了解并掌握与进程间通信IPC中的3个对象:共享内存、信号灯数组、消息队列到呢个有关的系统调用,并能熟练的掌握。

2、阅读实验题目并分析实验的需求。

理发店问题:假设理发店的理发室中有3个理发椅子和3个理发师,有一个可容纳4个顾客坐等理发的沙发。

此外还有一间等候室,可容纳13位顾客等候进入理发室。

顾客如果发现理发店中顾客已满(超过20人),就不进入理发店。

在理发店内,理发师一旦有空就为坐在沙发上等待时间最长的顾客理发,同时空出的沙发让在等候室中等待时间最长的的顾客就坐。

顾客理完发后,可向任何一位理发师付款。

但理发店只有一本现金登记册,在任一时刻只能记录一个顾客的付款。

理发师在没有顾客的时候就坐在理发椅子上睡眠。

理发师的时间就用在理发、收款、睡眠上。

(1)首先创建ipc.h文件,在里面定义生产者/消费者共用的IPC函数的原型和变量。

(2)然后创建ipc.c文件,在里面定义生产者/消费者共用的IPC 的具体的相应函数。

(3)创建sofa_control文件,在里面声明两个消息队列,当沙发空闲时则会将空闲的消息放入相应的队列中,让顾客可以进入沙发中,当理发师空闲时,也会将相应的消息放入队列中,从而可以让顾客到理发椅上进行理发。

(4)创建room_control文件,在里面创建消息队列,当等待室里的人数少于十三个时,若从消息队列中获得信息,则顾客可以进入,当沙发上有空位时,在等待室的人可以进入沙发等待。

(5)创建customer文件,里面声明两个消息队列,当获得允许进入的信息时,顾客进入等待室,当顾客理完发则会离开,同时向消息队列中发送信息。

(6)创建barber文件,在里面声明三个队列,当理发师就绪则会向队列中发送消息,若顾客收到消息就会去理发,当顾客离开时,也会想队列中发送一条消息。

同时理发师理发与收账是互斥的。

通过上述的文件就可以实现相应的功能。

3、分析清楚实验要求,便开始用编程语言进行编程,将分析的思路用编程语言实现。

4、完成编写程序,要进行运行调试,找到编写中的错误,进行进一步的修改,直到程序运行过程中不再出现错误.5、完成程序的调试与修改,保存程序,对编程的过程进行总结,找到编程中的不足,并完成实验报告结论分析与体会:结论:利用 IPC机制中的消息队列来实现相应的功能。

通过往队列中放入信和从队列中获取信息来实现进程间的通信,当顾客少于三个时,理师可以接给顾客理发并收取费用;当顾客多于三个少于七个时顾客要在沙发等待,理发师给顾客理完发然后等待簿进行记账;当顾客多于七个时,四个顾客在沙发上等,其他的在等待室等待,直到沙发空出才能从等待室到沙发,然后每给一个顾客理完发,则理发师等待账簿进行记账。

通过建立多个消息队列就可以实现相应的功能。

体会:1、通过实验对进程同步与互斥概念有了更深入的了解,加深了解了进程同步与互斥的效果。

2、加深了对非对称性互斥问题有关概念的理解,并进一步掌握了对经典问题的解法。

3、进一步熟练掌握了进程间通信有关的系统调用,并学会用它们进行编程和调试。

4、通过实验对相应的知识有了深入的理解,对编程软件也更熟练的掌握。

代码实现如下:ipc.c代码部分:#include "ipc.h"/** get_ipc_id() 从/proc/sysvipc/文件系统中获取 IPC 的 id 号* pfile: 对应/proc/sysvipc/目录中的 IPC 文件分别为*msg-消息队列,sem-信号量,shm-共享内存* key: 对应要获取的 IPC 的 id 号的键值*/int get_ipc_id(char *proc_file,key_t key){FILE *pf;int i,j;char line[BUFSZ],colum[BUFSZ];if((pf = fopen(proc_file,"r")) == NULL){perror("Proc file not open");exit(EXIT_FAILURE);}fgets(line, BUFSZ,pf);while(!feof(pf)){i = j = 0;fgets(line, BUFSZ,pf);while(line[i] == ' ') i++;while(line[i] !=' ') colum[j++] = line[i++];colum[j] = '\0';if(atoi(colum) != key) continue;j=0;while(line[i] == ' ') i++;while(line[i] !=' ') colum[j++] = line[i++];colum[j] = '\0';i = atoi(colum);fclose(pf);return i;}fclose(pf);return -1;}/** 信号灯上的 down/up 操作* semid:信号灯数组标识符* semnum:信号灯数组下标* buf:操作信号灯的结构*/int down(int sem_id){struct sembuf buf;buf.sem_op = -1;buf.sem_num = 0;buf.sem_flg = SEM_UNDO;if((semop(sem_id,&buf,1)) <0) { perror("down error ");exit(EXIT_FAILURE);}return EXIT_SUCCESS;}int up(int sem_id){struct sembuf buf;buf.sem_op = 1;buf.sem_num = 0;buf.sem_flg = SEM_UNDO;if((semop(sem_id,&buf,1)) <0) {perror("up error ");exit(EXIT_FAILURE);}return EXIT_SUCCESS;}/** set_sem 函数建立一个具有 n 个信号灯的信号量*如果建立成功,返回一个信号灯数组的标识符 sem_id*输入参数:* sem_key 信号灯数组的键值* sem_val 信号灯数组中信号灯的个数* sem_flag 信号等数组的存取权限*/int set_sem(key_t sem_key,int sem_val,int sem_flg){int sem_id;Sem_uns sem_arg;//测试由 sem_key 标识的信号灯数组是否已经建立if((sem_id = get_ipc_id("/proc/sysvipc/sem",sem_key)) < 0 ){//semget 新建一个信号灯,其标号返回到 sem_idif((sem_id = semget(sem_key,1,sem_flg)) < 0){perror("semaphore create error");exit(EXIT_FAILURE);}//设置信号灯的初值sem_arg.val = sem_val;if(semctl(sem_id,0,SETVAL,sem_arg) <0){perror("semaphore set error");exit(EXIT_FAILURE);}}return sem_id;}/** set_shm 函数建立一个具有 n 个字节的共享内存区*如果建立成功,返回一个指向该内存区首地址的指针 shm_buf *输入参数:* shm_key 共享内存的键值* shm_val 共享内存字节的长度* shm_flag 共享内存的存取权限*/char * set_shm(key_t shm_key,int shm_num,int shm_flg){int i,shm_id;char * shm_buf;//测试由 shm_key 标识的共享内存区是否已经建立if((shm_id = get_ipc_id("/proc/sysvipc/shm",shm_key)) < 0 ){//shmget 新建一个长度为 shm_num 字节的共享内存,其标号返回到 shm_id if((shm_id = shmget(shm_key,shm_num,shm_flg)) <0){perror("shareMemory set error");exit(EXIT_FAILURE);}//shmat 将由 shm_id 标识的共享内存附加给指针 shm_bufif((shm_buf = (char *)shmat(shm_id,0,0)) < (char *)0){perror("get shareMemory error");exit(EXIT_FAILURE);}for(i=0; i<shm_num; i++) shm_buf[i] = 0; //初始为 0}//shm_key 标识的共享内存区已经建立,将由 shm_id 标识的共享内存附加给指针 shm_bufif((shm_buf = (char *)shmat(shm_id,0,0)) < (char *)0){perror("get shareMemory error");exit(EXIT_FAILURE);}return shm_buf;}/** set_msq 函数建立一个消息队列* 如果建立成功,返回一个消息队列的标识符 msq_id* 输入参数:* msq_key 消息队列的键值* msq_flag 消息队列的存取权限*/int set_msq(key_t msq_key,int msq_flg){int msq_id;//测试由 msq_key 标识的消息队列是否已经建立if((msq_id = get_ipc_id("/proc/sysvipc/msg",msq_key)) < 0 ) {//msgget 新建一个消息队列,其标号返回到 msq_idif((msq_id = msgget(msq_key,msq_flg)) < 0){perror("messageQueue set error");exit(EXIT_FAILURE);}}return msq_id;}ipc.h部分代码:#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/sem.h>#include <sys/msg.h>#define BUFSZ 256#define MAXVAL 100#define STRSIZ 8#define CUSTOM 1 //读写完成标识/*信号灯控制用的共同体*/ typedef union semuns {int val;} Sem_uns;/* 消息结构体*/typedef struct msgbuf {long mtype;int mid;} Msg_buf;/*消息信息结构体typedef struct msqid_ds { struct ipc_perm msg_perm;struct msg *msg_first;struct msg *msg_last;time_t msg_stime;time_t msg_rtime;time_t msg_ctime;struct wait_queue *wwait;struct wait_queue *rwait;ushort msg_cbytes;ushort msg_qnum;ushort msg_qbytes;ushort msg_lspid;ushort msg_lrpid; }Msqid_ds;*/key_t book_key;// 记账簿信号灯int book_sem;int sem_flg;int quest_flg;key_t quest_key;//椅子消息队列int quest_id;int respond_flg;//等候室消息队列key_t respond_key;int respond_id;int get_ipc_id(char *proc_file,key_t key);//ipc.c中函数声明char *set_shm(key_t shm_key,int shm_num,int shm_flag);int set_msq(key_t msq_key,int msq_flag);int set_sem(key_t sem_key,int sem_val,int sem_flag);int down(int sem_id);int up(int sem_id);barber部分代码:#include "ipc.h"//int rand() { //用于产生生产者需要的随机数,随机数为0、1、2、3、4srand((unsigned)time(NULL));//return random() % 5;//}int main(int argc,char *argv[]){int i,j,k,t,flg =0,count,m = 0;int pid [3];Msg_buf msg_arg;struct msqid_ds msg_inf;//消息信息结构体//信号灯的值book_key = 101;sem_flg = IPC_CREAT | 0644;book_sem = set_sem(book_key,1,sem_flg);//建立一条沙发队列quest_flg = IPC_CREAT| 0644;quest_key = 201;quest_id = set_msq(quest_key,quest_flg);//建立一条等候室队列respond_flg = IPC_CREAT|0644;respond_key = 202;respond_id = set_msq(respond_key,respond_flg); //理发师程序执行循环过程printf("Wait customer \n");for(j = 0;j<3;j++)//循环的创建3个字程序{if((pid[j] = fork())<0){perror("process not create");exit(EXIT_FAILURE);}if(pid[j] == 0)break;}customer部分代码:#include "ipc.h"//int rand() { //用于产生生产者需要的随机数,随机数为0、1、2、3、4中的其一//srand((unsigned)time(NUL L));//return random() % 5;//}int main(int argc,char *argv[]){int i,j,k,t,count = 1;Msg_buf msg_arg;struct msqid_ds msg_inf;//消息队列信息结构体//创建信号灯book_key = 101;sem_flg = IPC_CREAT | 0644;book_sem = set_sem(book_key,1,sem_flg);//建立沙发消息队列quest_flg = IPC_CREAT| 0644;quest_key = 201;quest_id = set_msq(quest_key,quest_flg);//建立等候消息队列respond_flg = IPC_CREAT|0644;respond_key = 202;respond_id = set_msq(respond_key,respond_flg);//程序的主体,while循环msg_arg.mtype = CUSTOM;while(1){//t=rand();//sleep(t+5);//随机的休眠,模拟顾客到来的时间sleep(4);if(msgctl(quest_id, IPC_STAT,&msg_inf)== 0) //以阻塞方式接收消息{j = msg_inf.msg_qnum;//沙发队列的消息数if(j<4)//向沙发队列中发送一条消息{msg_arg.mid = count;//送入顾客的编号msgsnd(quest_id,&msg_arg,sizeof(msg_arg),0);printf("%d 号新顾客坐入沙发\n",count++);}if(j==4){if (msgctl(respond_id, IPC_STAT,&msg_inf)== -1)//取等候队列的消息结构体{printf("2 error\n");}k = msg_inf.msg_qnum;//等候队列的消息数if(k<13){msg_arg.mid = count;msgsnd(respond_id,&msg_arg,sizeof(msg_arg),0);//沙发队列已满等候队列发送消息printf("沙发坐满%d 号新顾客坐入等候室\n",count++);}else{printf("理发店人满\n");//理发店已满}}}else{printf("1 error\n");}}pause();return EXIT_SUCCESS;//程序结束}removeipc.c部分代码:#include "ipc.h"int main(){book_key = 101;quest_key = 201;respond_key = 202;int id;Sem_uns sem_arg;if((id=get_ipc_id("/proc/sysvipc/sem",book_key))>=0){//删除已经建立的信号灯semctl(id,0,IPC_RMID,sem_arg);}if((id=get_ipc_id("/proc/sy svipc/msg",quest_key))>=0){//删除已经建立的请求消息队列msgctl(id,IPC_RMID,NULL);if((id=get_ipc_id("/proc/sysvipc/msg",respond_key))>=0){//删除已经建立的响应消息队列msgctl(id,IPC_RMID,NULL);}return 0;}。

相关文档
最新文档