操作系统课程设计---理发师问题的实现
- 格式:doc
- 大小:526.00 KB
- 文档页数:19
睡眠理发师问题1 #include<stdio.h>2 #include<windows.h>3#define random (rand()*10000)/RAND_MAX //⽤来产⽣随机数4int main()5 {6int c;//沙发数7int customers=0;//顾客数8int count=0;//循环中⽤来计量的9int w=0;//等候理发的⼈数10int finish=0;//已经理完发的⼈数11int work1=0,work2=0,work3=0;//理发师是否在⼯作12int sleeping1=0,sleeping2=0,sleeping3=0; //理发师是否在休息13char opendoor; //理发店是否开门接待顾客14char blank; //获取空⽩字符15 printf("请输⼊理发店内沙发数量:\n");16 scanf("%d",&c);17 blank=getchar();18 printf("理发店内总共有%d张沙发。
\n",c);19 printf("是否营业?y/n\n");20 opendoor=getchar();2122while(opendoor!='y')23 {24 printf("对不起,理发店还没有开门!\n");25 blank=getchar();26 printf("是否营业?y/n\n");27 opendoor=getchar();28 }29 printf("开门营业!\n");30if(random%2)31 {//刚开门时随机产⽣顾客,分有顾客和没顾客两种情况,若为真,则有顾客32 Loop:for(count=0;random%2 && count<=5;count++)33 {34 customers++;35 printf("第%d个顾客到来了。
理发师问题-信号量实现版问题描述:⼀个理发店由⼀个有⼏张椅⼦的等待室和⼀个放有⼀张理发椅的理发室组成。
1.若没有要理发的顾客,则理发师去睡觉;2.若⼀顾客进⼊理发店,理发师正在为别⼈理发,且等待室有空椅⼦,则该顾客就找张椅⼦按顺序坐下;3.若⼀顾客进⼊理发店,理发师在睡觉,则叫醒理发师为该顾客理发;4.若⼀顾客进⼊理发店且所有椅⼦都被占⽤了,则该顾客就离开。
伪码实现:引⼊3个信号量和⼀个控制变量:1)控制变量waiting⽤来记录等候理发的顾客数,初值均为0;2)信号量customers⽤来记录等候理发的顾客数,并⽤作阻塞理发师进程,初值为0;3)信号量barbers⽤来记录正在等候顾客的理发师数,并⽤作阻塞顾客进程,初值为0(刚开始时理发师在睡觉,所以理发师这个资源数⽬为0);4)信号量mutex⽤于互斥,初值为1.关于p,v操作:P操作可以看做是申请⼀个资源,不管这个资源有没有都将这个资源的数⽬减1,如果现在资源数⽬⼩于0,就阻塞。
v操作就是释放资源,先将这个资源的数⽬加1,如果发现这个资源数⽬⼩于等于0,就会唤醒在阻塞队列上的⼀个进程看看PV原语实现:1顾客信号量 = 02理发师信号量 = 03互斥信号量mutex = 1// 椅⼦是理发师和顾客精进程都可以访问的临界区4int空椅⼦数量 = N //所有的椅⼦数量56理发师(线程/进程)7 While(true){ //持续不断地循环8 P(顾客)//试图为⼀位顾客服务,如果没有他就睡觉(进程阻塞)9 P(互斥信号量)//如果有顾客,这时他被叫醒(理发师进程被唤醒),要修改空椅⼦的数量10空椅⼦数量++ //⼀张椅⼦空了出来11 V(理发师)//现在有⼀个醒着的理发师,理发师准备理发,多个顾客可以竞争理发师互斥量,但是只有⼀个顾客进程可以被唤醒并得到服务12 V(互斥信号量)//释放椅⼦互斥量,使得进店的顾客可以访问椅⼦的数量以决定是否进店等待13/* 理发师在理发 */14}151617顾客(线程/进程)18while(true)19{//持续不断地循环20 P(互斥信号量)//想坐到⼀张椅⼦上21if (空椅⼦数量 > 0)22 { //如果还有空着的椅⼦的话23空椅⼦数量-- //顾客坐到⼀张椅⼦上了24 V(顾客)//通知理发师,有⼀位顾客来了25 V(互斥信号量)//顾客已经坐在椅⼦上等待了,访问椅⼦结束,释放互斥量26 P(理发师)//该这位顾客理发了,如果理发师还在忙,那么他就等着(顾客进程阻塞)27/* 竞争到了理发师则该顾客开始理发 */28 }29else30{//没有空着的椅⼦31 V(互斥信号标)//不要忘记释放被锁定的椅⼦32/* 顾客没有理发就⾛了 */33}34}⾸先是信号量的实现版本:1 #include <stdio.h>2 #include <semaphore.h>3 #include <pthread.h>4#define CHAIRS 356//这个计数器才是共享资源7int waiting=0; //控制变量, ⽤来记录等候理发的顾客数89 sem_t customers; //⽤来记录等候理发的顾客数,并⽤作阻塞理发师进程10 sem_t barbers; //⽤来记录正在等候顾客的理发师数,并⽤作阻塞顾客进程11 sem_t mutex; //⽤于线程互斥1213void cut_hair()14 {15 printf("理发ing\n");16 }1718void sleeping()19 {20 printf("sleeping\n");21 }2223void *barber(void *arg)24 {25while(1){26 sem_wait(&customers); //若⽆顾客,理发师睡眠27 sem_wait(&mutex);28 waiting--;29 printf("理发师:等待顾客-1,还剩%d⼈等待 \n", waiting);30 sem_post(&barbers);31 sem_post(&mutex);32 cut_hair(); //理发ing, 这个时候顾客已经独享理发师了,所以不在临界区3334 sem_wait(&mutex);35if(waiting==0){ //没⼈就长眠去呗36 sem_post(&mutex);37break;38 }39 sem_post(&mutex);40 }41 pthread_exit(NULL);42 }4344void get_cut()45 {46 printf("顾客%u: 理发ing\n",(unsigned int)pthread_self());47 }4849void *customer(void *arg)50 {51 sem_wait(&mutex); //互斥52if(waiting < CHAIRS){ //等候的⼈⽐椅⼦少53 waiting++; //等候的⼈+154 sem_post(&customers); //多了⼀个顾客55 sem_post(&mutex);56 sem_wait(&barbers); //如果没有理发师了,那顾客就在椅⼦上等着57 get_cut();58 }59else{60 printf("顾客%u: 没椅⼦了,⾛⼈ \n", (unsigned int)pthread_self());61 sem_post(&mutex);62 }63 sem_post(&mutex); //如果前⾯没有椅⼦了,就直接⾛了64 pthread_exit(NULL);65 }66676869int main(int argc, char const *argv[])70 {71void * retval;72int res=0;73int i;74 sem_init(&customers, 0, 0); //没有顾客75 sem_init(&barbers, 0, 0); //没有理发师,都在睡觉呢76 sem_init(&mutex, 0, 1); //实现互斥7778 pthread_t bar, cus[6];79 res+=pthread_create(&bar, NULL, barber, NULL);80for(i=0; i<6; i++){81 res+=pthread_create(&cus[i], NULL, customer, NULL);82 }83if(res!=0){84 printf("线程创建失败!\n");85 pthread_exit(NULL);86 }87 printf("线程创建成功\n");88 pthread_join(bar,&retval);89for(i=0; i<6; i++){90 pthread_join(cus[i],&retval);91 }92return0;93 }。
操作系统理发师课程设计一、教学目标本课程的学习目标包括:1.知识目标:学生能够理解操作系统的概念、原理和功能,掌握操作系统的基本设计和实现方法,了解操作系统的历史和发展趋势。
2.技能目标:学生能够使用操作系统进行基本的上机操作,能够使用操作系统提供的工具和命令进行系统管理和维护,能够编写简单的操作系统程序。
3.情感态度价值观目标:学生能够认识到操作系统在现代社会中的重要性和地位,培养对操作系统的兴趣和热情,培养良好的编程习惯和团队合作精神。
二、教学内容本课程的教学内容主要包括:1.操作系统的概念和原理:操作系统的定义、作用、基本组成和运行机制。
2.操作系统的功能和特性:进程管理、内存管理、文件系统、输入输出系统等。
3.操作系统的实例:Windows、Linux、macOS等主流操作系统的特点和比较。
4.操作系统的编程:操作系统编程的基本概念和方法,常用的操作系统编程语言和工具。
三、教学方法本课程的教学方法包括:1.讲授法:通过教师的讲解和讲解资料的展示,向学生传授操作系统的概念和原理。
2.讨论法:通过小组讨论和课堂讨论,引导学生深入思考和理解操作系统的功能和特性。
3.案例分析法:通过分析具体的操作系统实例,让学生了解不同操作系统的特点和应用场景。
4.实验法:通过上机实验和编程实践,让学生掌握操作系统的基本操作和编程方法。
四、教学资源本课程的教学资源包括:1.教材:选用权威、实用的操作系统教材,作为学生学习的主要参考资料。
2.参考书:提供相关的操作系统参考书籍,供学生深入学习和研究。
3.多媒体资料:制作精美的PPT和教学视频,辅助讲解和展示操作系统的概念和实例。
4.实验设备:提供计算机实验室和必要的编程工具,让学生进行上机实验和编程实践。
五、教学评估本课程的评估方式包括:1.平时表现:通过学生的课堂参与、提问回答、小组讨论等表现,评估学生的学习态度和理解程度。
2.作业:通过学生完成的作业,评估学生对课程内容的掌握和应用能力。
课程实验报告题目计算机操作系统理发师问题姓名潘 *学号 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 总体设计思想及开发环境与工具................................................................ 错误!未定义书签。
理发师问题操作系统课程设计河南城建学院《操作系统》课程设计报告课程名称: 《操作系统》课程设计设计题目: 理发师问题指导教师: 李蓓耿永军班级:学号:学生姓名:同组人员:成绩:评语:计算机科学与工程学院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,则此线程获得一个通行证,这将导致信号量的计数递减,否则,此线程将阻塞直到获得一个通行证为止。
课程设计报告课程名称操作系统课题名称嗜睡的理发师问题专业信息管理与信息系统班级学号姓名指导教师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++中处理进程、信号的函数不熟,所以有许多参考了网上的代码。
⏹理发师问题:一个理发店由一间等候室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把用来等候理发的椅子。
《操作系统原理》课程设计任务书题目:理发师问题的实现学生姓名:黄田丰学号:10240221班级:计算机二班题目类型:软件工程(R)指导教师:李睿一、设计目的学生通过该题目的设计过程,掌握理发师问题的原理、软件开发方法并提高解决实际问题的能力。
二、设计任务1、了解UNIX的命令及使用格式,熟悉UNIX/LINUX的常用基本命令,练习并掌握UNIX提供的vi编辑器来编译C程序,学会利用gcc、gdb编译、调试C程序。
2、编写程序实现理发师问题。
一个理发店有一间配有n个椅子的等待室和一个有理发椅的理发室。
如果没有顾客被服务,理发师就去睡觉。
如果顾客来时所有的椅子上都有人,那么顾客离去。
如果理发师在忙而有空闲的椅子,那么顾客就会坐在其中的一个椅子上。
如果理发师在睡觉,顾客会摇醒他。
三、设计要求1、分析设计要求,给出解决方案(要说明设计实现所用的原理、采用的数据结构)。
2、设计合适的测试用例,对得到的运行结果要有分析。
3、设计中遇到的问题,设计的心得体会。
4、文档:课程设计打印文档每个学生一份,并装在统一的资料袋中,资料袋前面要贴有学校统一的资料袋封面。
5、光盘:每个学生文档和程序资料分别建在一个以自己学号和姓名命名的文件夹下,并要求每班负责人汇总每个学生的文件放在以班级姓名命名的文件夹下,刻录成5寸光盘,并复制四份(共五张内容相同的光盘),放在一个专门的资料袋中,不必再装软盘四、提交的成果1. 设计任务书一本(学校统一格式)2. 设计说明书一份,内容包括:1) 中文摘要100字;关键词3-5个;2) 设计思想;3)各模块的伪码算法;4)函数的调用关系图;5)测试结果;6)设计总结;7) 参考文献、致谢等。
五、主要参考文献1. 汤子瀛,哲凤屏.《计算机操作系统》.西安电子科技大学学出版社.2. 王清,李光明.《计算机操作系统》.冶金工业出版社.3.孙钟秀等. 操作系统教程. 高等教育出版社4.曾明. Linux操作系统应用教程. 陕西科学技术出版社.5. 张丽芬,刘利雄.《操作系统实验教程》. 清华大学出版社.6. 孟静,操作系统教程--原理和实例分析. 高等教育出版社7. 周长林,计算机操作系统教程. 高等教育出版社8. 张尧学,计算机操作系统教程,清华大学出版社9.任满杰,操作系统原理实用教程,电子工业出版社六、各阶段时间安排(共2周)周次日期内容地点完成情况教师签字第1周星期一~二教师讲解设计要求查找参考资料教室图书馆星期三~五算法设计,编程实现实验室第2周星期一~三算法设计,编程实现实验室星期四~五检查程序,答辩实验室。
操作系统课程设计、管路敷设技术通过管线不仅可以解决吊顶层配置不规范高中资料试卷问题,而且可保障各类管路习题到位。
在管路敷设过程,要加强看护关于管路高中资料试卷连接管口处理高中资料试卷弯扁度固定盒位置保护层防腐跨接地线弯曲半径标高等,要求技术交底。
管线敷设技术包含线槽、管架等多项方式,为解决高中语文电气课件中管壁薄、接口不严等问题,合理利用管线敷设技术。
线缆敷设原则:在分线盒处,当不同电压回路交叉时,应采用金属隔板进行隔开处理;同一线槽内,强电回路须同时切断习题电源,线缆敷设完毕,要进行检查和检测处理。
、电气课件中调试对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料试卷相互作用与相互关系,根据生产工艺高中资料试卷要求,对电气设备进行空载与带负荷下高中资料试卷调控试验;对设备进行调整使其在正常工况下与过度工作下都可以正常工作;对于继电保护进行整核对定值,审核与校对图纸,编写复杂设备与装置高中资料试卷调试方案,编写重要设备高中资料试卷试验方案以及系统启动方案;对整套启动过程中高中资料试卷电气设备进行调试工作并且进行过关运行高中资料试卷技术指导。
对于调试过程中高中资料试卷技术问题,作为调试人员,需要在事前掌握图纸资料、设备制造厂家出具高中资料试卷试验报告与相关技术资料,并且了解现场设备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
、电气设备调试高中资料试卷技术电力保护装置调试技术,电力保护高中资料试卷配置技术是指机组在进行继电保护高中资料试卷总体配置时,需要在最大限度内来确保机组高中资料试卷安全,并且尽可能地缩小故障高中资料试卷破坏范围,或者对某些异常高中资料试卷工况进行自动处理,尤其要避免错误高中资料试卷保护装置动作,并且拒绝动作,来避免不必要高中资料试卷突然停机。
因此,电力高中资料试卷保护装置调试技术,要求电力保护装置做到准确灵活。
课程实验报告题目计算机操作系统理发师问题姓名潘 *学号 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);// 临界区互斥访问信号量(二进制信号量),相当于互斥锁。
)*******************实践教学*******************兰州理工大学(计算机与通信学院2011年秋季学期操作系统课程设计<题目:理发师问题的实现专业班级:计算机科学与技术姓名:学号:指导教师:成绩:【摘要理发师问题是一个利用信号量进行PV操作的经典问题。
设计程序实现此问题,要使得理发师的活动与顾客的活动得到各自真实的模拟。
所执行的程序应体现:理发师在没有顾客的时候去睡觉,有顾客则工作;顾客在理发师工作时坐下等待,无座时离开,直至等到理发师自己理发。
关键字:理发师,顾客,PV操作。
#)目录摘要 (2)1 设计要求 (4)初始条件 (4)技术要求 (4)2 总体设计思想及开发环境与工具 (4)总体设计思想 (4)多线程编程原理 (5);创建一个线程 (5)等待一个线程结束 (5)信号量 (6)伪码实现 (6)开发环境与工具 (8)3数据结构与模块说明 (8)数据结构 (8)函数的调用关系图 (8);主函数模块 (8)理发师模块 (9)顾客模块 (10)5运行结果 (10)运行步骤 (10)测试结果 (11)编辑,编译和运行的过程图 (11)错误部分截图 (12)》正确运行结果图 (12)设计总结 (16)参考文献 (17)致谢 (18)附录(源程序代码) (19)\1 设计要求初始条件(1)操作系统:Linux(2)程序设计语言:C语言(3)设有一个理发师,5把椅子(另外还有一把理发椅),几把椅子可用连续存储单元。
-技术要求(1)为每个理发师/顾客产生一个线程,设计正确的同步算法(2)每个顾客进入理发室后,即时显示“Entered”及其线程自定义标识,还同时显示理发室共有几名顾客及其所坐的位置。
(3)至少有10个顾客,每人理发至少3秒钟。
(4)多个顾客须共享操作函数代码。
2 总体设计思想及开发环境与工具总体设计思想题目中要求描述理发师和顾客的行为,因此需要两类线程barber()和customer ()分别描述理发师和顾客的行为。
其中,理发师有活动有理发和睡觉两个事件;等待和理发二个事件。
店里有固定的椅子数,上面坐着等待的顾客,顾客在到来这个事件时,需判断有没有空闲的椅子,理发师决定要理发或睡觉时,也要判断椅子上有没有顾客。
所以,顾客和理发师之间的关系表现为:!(1)理发师和顾客之间同步关系:当理发师睡觉时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师睡觉。
(2)理发师和顾客之间互斥关系:由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n把,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。
(3)故引入3个信号量和一个控制变量:ⅰ控制变量waiting用来记录等候理发的顾客数,初值为0;ⅱ信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;ⅲ信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为1;ⅳ信号量mutex用于互斥,初值为1多线程编程原理此次在Linux下进行多线程编程需要用到pthread_create和pthread_join这两个函数。
>2.2.1 创建一个线程pthread_create用来创建一个线程,原型为:extern int pthread_create((pthread_t *__thread, __const pthread_attr_t *__attr,void *(*__start_routine) (void *), void *__arg))第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。
函数thread不需要参数时,最后一个参数设为空指针。
第二个参数设为空指针时,将生成默认属性的线程。
创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。
2.2.2 等待一个线程结束pthread_join用来等待一个线程的结束,函数原型为:extern int pthread_join __P ((pthread_t __th, void **__thread_return)); 第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被\等待的线程结束为止,当函数返回时,被等待线程的资源被收回。
2.2.3 信号量(1)函数sem_init()用来初始化一个信号量,函数原型为:extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。
(2)函数sem_post( sem_t *sem )用来增加信号量的值。
当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。
(3)函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。
函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。
&伪码实现difine n 5;3.2.1 3.2.23.2.3SleepingBarber 测试结果编辑,编译和运行的过程图\¥|5.2.2 错误部分截图正确运行结果图第一次运行结果如下图:第二次运行结果如下图:—~第三次运行结果如下图;'设计总结两周的的操作系统课程设计终于完成了,回想这两周的努力,感触良多。
拿到题目时我不知从何下手,想想自己对Liunx一无所知,无奈,只好去查阅相关书籍,并在网上查找了相关资料,了解了linux多线程编程的原理,应注意的问题,及一些常用命令;第一周先设计出了该程序的伪代码即其wait、signal操作。
然后,根据其要求进行编程,由于使用的是多线程编程,开始进行编译的时候,编译命令输入错误,没有输入-lpthread,程序总是出现错误。
同时,创建线程函数时,由于对其格式输入错误导致程序无法运行。
例如,等都为本次调试时的程序。
第二周主要是不断的调试并完善程序。
程序可以运行,但与要求总有些不符,故不断的进行修改,并对其输出的格式进行完善,使其输出看起来美观一些,容易观察一些。
例如,等程序为此次调试结果。
然后是在原有代码的基础上,使程序更完整些。
并进行结果的截图,开始设计并编写课程设计说明书。
通过本次编程我熟悉了linux 下的多线程编程和信号量实现wait、signal 操作的全过程,对同步和互斥问题也有了更深一步的理解,同时,也使我对linux 编程有了更多的了解,在很多方面,它与在windows下编程有着很大的不同,对与多线程来说更方便一些。
设计过程中也遇到不少困难,尤其是对于多线程的实现,结果总是不如想象中完美。
比如其顾客编号的输出有时会不按顺序,输入有点乱。
另外,有时,输出结束后,程序仍无法结束,必须强制性关闭终端才可以结束程序,这是本程序的一个不足之处。
在本次课程设计中我深深感觉到自己掌握的知识还远远不够,我明白光是知道书本上的知识是远远不够的,一定要把理论知识和实践结合起来。
同时,要多多学习linux的操作。
]参考文献1. 汤子瀛,哲凤屏.《计算机操作系统》.西安电子科技大学学出版社.2. 王清,李光明.《计算机操作系统》.冶金工业出版社.3.孙钟秀等. 操作系统教程. 高等教育出版社4.曾明. Linux操作系统应用教程. 陕西科学技术出版社.5. 张丽芬,刘利雄.《操作系统实验教程》. 清华大学出版社.6. 孟静,操作系统教程--原理和实例分析. 高等教育出版社7. 周长林,计算机操作系统教程. 高等教育出版社~8. 张尧学,计算机操作系统教程,清华大学出版社9.任满杰,操作系统原理实用教程,电子工业出版社…&致谢在此次课程设计的过程中,我首先要感谢我的指导老师张永老师,给了我很大的帮助,与此同时感谢宿舍的舍友,对此次课程设计的程序的调试工作给予了大力的帮助。
…)附录(源程序代码)##include<>#include<>#include<>#include<>#include<>#include<>#include<>#define n 5 //the shop have five chairs"//design three semaphores: mutex,customer,barbers sem_t mutex,customers,barbers;int waiting=0; //the number of waiting customers int chair[5];void * barber();void * customer(void *arg);{int main(int argc,char *argv[]){//create 10 semaphores and one Barber semaphorepthread_t Customer_id[10],Barber_id;int i;sem_init(&mutex,0,1); //init mutex semaphore to 1sem_init(&customers,0,0);//init semaphore customers to 0sem_init(&barbers,0,1);~for(i=0;i<5;i++)pthread_create(&Barber_id,NULL,(void*)barber,NULL);for (i=0;i<10;i++)pthread_create(&Customer_id[i],NULL,(void*)customer,(void*)(i+1)); for (i=0;i<10;i++)pthread_join(Customer_id[i],NULL);for(i=0;i<5;i++)、pthread_join(Barber_id,NULL);return 0;}//creat barber pthreadvoid * barber(){int i;¥int next;//wait(customers),if no customers,barber sleepingsem_wait(&customers);sem_wait(&mutex); //wait(mutex)waiting--; //the numer of waiting reduce onefor(i=0;i<5;i++){if (chair[i]!=0).{next= chair[i];chair[i]=0;break;}}printf("The barber is cutting %dth customer's hair\n",next); sleep(3);~sem_post(&mutex);sem_post(&barbers);}//creat customer pthreadvoid * customer(void *arg){int i;~sem_wait(&mutex); //wait(mutex) if(waiting<n)if(waiting<n){waiting++; //the numer of waiting plus onefor(i=0;i<5;i++){if (chair[i]==0){chair[i]=(int)arg;break;}}printf("***************************************************\n");printf("Entered:Number %d customer comes,and sits at %d chair \n",(int)arg,(i+1));printf("There are %d customer on the chair\n",waiting);printf("The customers' location are:");for(i=0;i<5;i++)printf("%d ",chair[i]);printf("\n");sleep(1);sem_post(&mutex); //signal(mutex)sem_post(&customers); //signal(customers)sem_wait(&barbers); //wait(barbers)}else{printf("Number %d comes,there are no chairs,the customer %d is leaving\n",(int)arg,(int)arg);sem_post(&mutex);}}。