用信号量解决理发店问题
山大操作系统实验5
进程同步实验张咪软件四班一、实验目的总结和分析示例实验和独立实验中观察到的调试和运行信息,说明您对与解决非对称性互斥操作的算法有哪些新的理解和认识?为什么会出现进程饥饿现象?本实验的饥饿现象是怎样表现的?怎样解决并发进程间发生的饥饿现象?您对于并发进程间使用消息传递解决进程通信问题有哪些新的理解和认识?根据实验程序、调试过程和结果分析写出实验报告。
二、实验要求理发店问题:假设理发店的理发室中有3个理发椅子和3个理发师,有一个可容纳4个顾客坐等理发的沙发。
此外还有一间等候室,可容纳13位顾客等候进入理发室。
顾客如果发现理发店中顾客已满(超过20人),就不进入理发店。
在理发店内,理发师一旦有空就为坐在沙发上等待时间最长的顾客理发,同时空出的沙发让在等候室中等待时间最长的的顾客就坐。
顾客理完发后,可向任何一位理发师付款。
但理发店只有一本现金登记册,在任一时刻只能记录一个顾客的付款。
理发师在没有顾客的时候就坐在理发椅子上睡眠。
理发师的时间就用在理发、收款、睡眠上。
请利用linux系统提供的IPC进程通信机制实验并实现理发店问题的一个解法。
三、实验环境实验环境均为Linux操作系统,开发工具为gcc和g++。
四、实验思路约束:1.设置一个count变量来对顾客进行计数,该变量将被多个顾客进程互斥地访问并修改,通过一个互斥信号量mutext来实现。
count>20时,就不进入理发店。
7<count<20时,count++,顾客申请等候室,进入等候室等待,用一个room信号量控制。
然后等待申请沙发,用一个sofa信号量控制。
然后申请椅子。
3<count<7时,count++,顾客坐在沙发上等待,等待申请椅子。
count<3时,count++,顾客坐在椅子上等待理发。
2.只有在理发椅空闲时,顾客才能做到理发椅上等待理发师理发,否则顾客便必须等待;只有当理发椅上有顾客时,理发师才可以开始理发,否则他也必须等待。
理发师问题-信号量实现版
理发师问题-信号量实现版问题描述:⼀个理发店由⼀个有⼏张椅⼦的等待室和⼀个放有⼀张理发椅的理发室组成。
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 }。
操作系统信号量习题
(一)图书馆有100个座位,每位进入图书馆的读者要在登记表上登记,退出时要在登记表上注销。
要几个程序?有多少个进程?(答:一个程序;为每个读者设一个进程)(1)当图书馆中没有座位时,后到的读者在图书馆为等待(阻塞)(2)当图书馆中没有座位时,后到的读者不等待,立即回家。
解(1 )设信号量:S=100; MUTEX=1P(S)P(MUTEX)登记V(MUTEX)阅读P(MUTEX)注销V(MUTEX)V(S)解(2)设整型变量COUNT=100; 信号量:MUTEX=1;P(MUTEX);IF (COUNT==0){ V(MUTEX);RETURN;}COUNT=COUNT-1;登记V(MUTEX);阅读P(MUTEX);COUNT=COUNT+1;V(MUTEX);RETURN;(二)有一座东西方向的独木桥;用P,V操作实现:(1)每次只允许一个人过桥;(2)当独木桥上有行人时,同方向的行人可以同时过桥,相反方向的人必须等待。
(3)当独木桥上有自东向西的行人时,同方向的行人可以同时过桥,从西向东的方向,只允许一个人单独过桥。
(此问题和读者与写者问题相同,东向西的为读者,西向东的为写者)。
(1)解设信号量MUTEX=1P (MUTEX)过桥V (MUTEX)(2)解设信号量:MUTEX=1 (东西方互斥)MD=1 (东向西使用计数变量互斥)设整型变量:CD=0 (东向西的已上桥人数) CX=0 (西向东的已上桥人数)从东向西:P (MD)IF (CD=0){P (MUTEX) }CD=CD+1V (MD)过桥P (MD)CD=CD-1IF (CD=0){V (MUTEX) }V (MD)从西向东:P (MX){P (MUTEX) }CX=CX+1V (MX)过桥P (MX)CX=CX-1IF (CX=0){V (MUTEX) }V (MX)(3) 解:从东向西的,和(2)相同;从西向东的和(1)相同。
第四章 理发店问题
理发店问题一家理发店由一间有n张沙发的等待室和一把理发椅的理发室组成。
如果没有顾客要理发,理发室就睡觉。
当顾客走进理发店时:(1)若是第一个到达的顾客,则他坐到理发椅上唤醒理发师,开始理发;(2)若不是到达的第一个顾客,而且等待室里所有的沙发都被占用,他便离开理发店;否则,他便找一张沙发坐下等待理发。
理发结束后,顾客必须付费,指导理发师收费并将收据给顾客后,顾客方可离开。
试用信号量机制实现这一同步问题。
(1)设置整型变量count,用于统计占用沙发的顾客数量,初始值为0;(2)设置5个信号量mutex、empty、full、payment、receipt,其中mutex用来实现对count的互斥访问,初始值为1;empty表示理发椅是否空闲,初始值为1;full表示理发椅上是否坐有等待理发的顾客,初始值为0;payment表示顾客等待付费,初始值为0;receipt 表示理发师填写收据,初始值为0.算法描述如下:int count=0;semaphore mutex=1,empty=1,full=0,payment=0,receipt=0;guest(){while(true){wait(mutex);if(count>=n){signal(mutex);离开理发店;}else{count++;signal(mutex);坐在沙发上等待理发;wait(empty); //等待理发椅变空离开沙发,坐到理发椅上;wait(mutex);count--;signal(mutex);signal(full); //唤醒理发师理发;付费;signal(payment); //通知理发师付费wait(receipt); //等待理发师的收据signal(empty); //离开理发椅}}}barber(){while(true){wait(full); //等待顾客把自己唤醒为顾客理发;wait(payment); //等顾客付费收费;signal(receipt); //将收据给顾客}}。
系统调用中的信号量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把用来等候理发的椅子。
计算机操作系统理发师问题-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);// 临界区互斥访问信号量(二进制信号量),相当于互斥锁。
信号量机制例题集2
Getout() { while(true) {p(readers); p(mutex); 消掉登记; 离开阅览室 v(mutex); v(seats); } }返回
信号量机制例题:吸烟者
有三个吸烟者和一个供应商,每个吸烟者制 造并吸掉香烟。制造和吸掉香烟需要三种原 料:烟草、纸和火柴。供货商有充足的原料, 而每个吸烟者手中只有一种不同于其他吸烟 者所拥有的原料。供货商放两种原料于桌面 上,于是正好有另一种原料的吸烟者就可以 制造并吸掉香烟,然后发一个完成信号给供 货商,于是供货商马上给出另两种原料,并 重复这个过程。
出租车
Semaphore:st=1,s=0, sc=1;
Customer () { p (sc); P (s); 乘坐离开; V (sc); V (st) }
taxi() { P (st); 停车; V (s); } 返回
信号量机制例题:爸爸,妈妈,儿子,女儿 • 桌上有一空盘,允许存放一只水果。 爸爸可向盘中放苹果,妈妈向盘中放 香蕉,儿子专等吃盘中的香蕉,女儿 专等吃盘中的苹果。
信号量机制例题:出租车
某宾馆门前有一个出租车停车位,假设宾馆 每一位顾客出门都要乘坐出租车,并且对顾 客约定:如果有其他顾客在此等车位等车, 则在旁等待;否则在此等车;此停车位有车 则乘坐。对出租车做出约定:如果此停车位 已停有车,则等待此停车位空闲;否则停到 此停车位等待顾客;有顾客则搭载顾客离开。 试用P、V原语编写程序描述顾客与出租车的 行为。
Else { p(sb); p(mutex); 将产品入库; v(mutex); v(sa);
返回
信号量机制例题:阅览室
有一个阅览室,共有100个座位,读者进入 时必须在一张登记表上登记,该表为每一座 位列一表目,包括做好和读者姓名等,读者 离开时要削掉登记的信息。
例题以及习题pv操作3
【实战3】理发师问题理发店有一位理发师、一把理发椅及三把供等候理发的顾客坐的椅子。
如果没有顾客,理发师就去睡觉。
如果顾客来时所有的椅子都有人,那么顾客就离去。
如果理发师在忙而有空闲的椅子,那么顾客就会坐在其中的一个空闲的椅子上。
如果理发师在睡觉,顾客会唤醒他。
请利用信号量(semaphores),写个程序来协调理发师和顾客进程。
【浙江大学2007】int count=0;//记录理发店里的顾客数量semaphore mutex=1;//用于互斥访问count变量所用的信号量semaphore barber_chair=0;//semaphore wait_chair=3;//顾客等待时可坐的椅子semaphore ready=0;//坐在等候椅子上等待理发的顾客数量Barber(){//理发师进程while(1){wait(ready);//是否有顾客在等待理发,没有则阻塞signal(barber_chair);//请等待时间最长的顾客坐到理发椅上signal(wait_chair);//坐到理发椅上的顾客让出一个等待时可坐的椅子barbering//给顾客理发}}Customer(){//顾客进程i{wait(mutex);if(count>=4){//如果理发店已经有四个顾客了signal(mutex);leave //走人}else{//理发店里顾客不足4个count++;//更新顾客人数signal(mutex);}wait(wait_chair);//先请求坐等待时坐的椅子signal(ready);//告诉理发师又有一位顾客准好了,等待理发wait(barber_chair);//再请求坐理发椅be barberedwait(mutex);count--;//更新店里的顾客人数signal(mutex);}}【练习1】 如图所示,有多个PUT 操作同时向BUFF1放数据,有一个MOVE 操作不断地将BUFF1的数据移到BUFF2,有多个GET 操作不断地从BUFF2中将数据取走。
操作系统--理发师问题
操作系统--理发师问题正文:一:背景介绍理发师问题是一个经典的并发编程问题,涉及到同时访问共享资源的多个线程之间的同步问题。
该问题的背景可以描述为:在一个理发店里,有一个理发师和一排等待理发的顾客,每个顾客需要等待一段时间才能坐到理发椅上理发。
当有空闲的理发师时,顾客就会坐到椅子上进行理发,否则就需要等待其他顾客理发结束。
该问题需要设计一个合理的算法,保证每个顾客都能够得到理发椅上的理发服务。
二:问题分析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,则此线程获得一个通行证,这将导致信号量的计数递减,否则,此线程将阻塞直到获得一个通行证为止。
系统调用中的信号量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把用来等候理发的椅子。
理发师问题
设计思想打瞌睡的理发师问题是一种同步问题的抽象描述。
计算机系统中的每个进程都可以消费或生产某类资源,当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。
而当某个进程释放资源时,则它就相当一个生产者。
因此此题可看作是n个生产者和1个消费者问题。
顾客作为生产者,每到来一个就使计数器count增加1,以便让理发师理发(相当于消费)至最后一个顾客(相当于产品)。
并且,第1个到来的顾客应负责唤醒理发师;如果不是第1个到达的顾客,则在有空椅子的情况下坐下等待,否则离开理发店(该消息可由计数器count获得)。
所以可以通过一个有界缓冲区把理发师和顾客联系起来。
而其中的信号也具有两种功能:一是跟踪资源的理发师和顾客的计数器;二是协调资源的理发师和顾客之间的同步器。
通过对信号进行P、V 操作来实现有关问题和相关描述。
一、数据结构:1、信号量:int Custom;//所有到达的顾客,包括正在被理发的顾客,所以一般情况下,Custom比Wait_Person大1.int Mutex;//用于实现全局变量Wait—preson访问的互斥int Wait_Leave;//等待离开信号量,用来表示几个顾客等待离开,只要理发师为其理发完毕,他就可以离开了2、PV操作伪代码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( );//一个顾客坐下等理/ }ElseV(mutex);//人满了,离开}。
理发店问题
#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模板
课程实验报告题目计算机操作系统理发师问题姓名潘 *学号 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);// 临界区互斥访问信号量(二进制信号量),相当于互斥锁。
课程设计--理发师系统1
摘要课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,当今计算机应用在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握计算机开发技术是十分重要的。
通过对《操作系统》这门课的学习后,要求我们能够在深刻理解和应用有关经典进程的同步和互斥问题之余,能够模拟解决打瞌睡的理发师问题。
要求以输出字符串的形式表示理发师和顾客的行为。
理发师问题是一个利用信号量进行P、V操作的经典问题。
设计程序实现此问题,要使得理发师的活动与顾客的活动得到各自真实的模拟。
所执行的程序应体现:理发师在没有顾客的时候去睡觉,有顾客则工作;顾客在理发师工作时坐下等待,无座时离开,直至等到理发师自己理发。
关键字:理发师;顾客;PV操作目录摘要 (1)1 设计要求 (1)1.1初始条件 (1)1.2技术要求 (1)2 需求分析 (2)2.1具体需求 (2)2.2系统实现步骤 (2)3 总体设计 (3)3.1总体设计思想 (3)3.2各功能之间的调用关系 (4)3.3创建数据结构 (6)4详细设计 (6)4.1控制营业开始的模块 (7)4.2建立一个理发类 (7)4.3理发功能模块 (8)5系统实现原理 (15)6程序运行界面 (18)6.1进入程序友好界面 (18)6.2理发店营业界面 (19)6.3理发店服务界面 (20)6.4 询问是否继续工作界面 (21)6.5 无顾客界面 (22)6.6理发店尚未营业的界面 (23)6.7退出程序的界面 (23)7 设计总结 (24)参考文献 (25)致谢 (26)附录 (27)1 设计要求1.1初始条件(1)操作系统:Windos(2)程序设计语言:C++语言(3)设有三个理发师,3把椅子(另外还有三把理发椅),几把椅子可用连续存储单元。
1.2技术要求(1)为每个理发师/顾客产生一个线程,设计正确的同步算法。
记录型信号量解决理发师问题
/*理完一人,还有顾
/*若无顾客,理发师
/*进程互斥*/ /*等候顾客数少一个
/*理发师去为一个顾 /*开放临界区*/ /*正在理发*/
procedure customer begin P(mutex); if waiting<CHAIRS begin waiting := waiting+1; V(customers); V(mutex); P(barbers); get-haircut( ); end V(mutex); end;
记录型信号量解决理发师问题
问题:理发店理有一位理发师、一把理发椅 和n把供等候理发的顾客坐的椅子 如果没有顾客,理发师便在理发椅上睡觉。 一个顾客到来时,它必须叫醒理发师 如果理发师正在理发时又有顾客来到,则如 果有空椅子可坐,就坐下来等待,否则就离开。
var waiting : integer; CHAIRS:integer;
/*等候理发的顾客数*/ /*为顾客准备的椅子数*/
customers, barbers,mutex : semaphore; customers := 0; barbers := 0; waiting := 0; mutex := 1;
Procedure barber; begin while(TRUE); 客吗?*/ P(cutomers); 睡眠*/ P(mutex); waiting := waiting – 1; */ V(barbers); 客理发*/ V(mutex); cut-hair( ); end;
/*进程互斥*/ /*看看有没有空椅子*/ /* 等候顾客数加1*/ /*必要的话唤醒理发师*/ /*开放临界区*/ /*无理发师, 顾客坐着养神*/ /*一个顾客坐下等理发*/
/*人满了,
利用整型信号量解决理发师问题
利用整型信号量解决理发师问题int waiting=0;//等候理发的人数,临界资源semaphore customers=0,barbers=0;//两个信号量,顾客和理发师semaphore mutex=1;//此信号量是为操作临界资源waiting而设的barber()//理发师进程{While(1){P(customers);//是否有顾客,若没有则理发师睡觉P(mutex);//当有顾客时,执行此语句,开始操作临界资源waitingwaiting--;//等候的人数减1V(barbers);//表明理发师空闲,可以理发了V(mutex);//开放临界资源理发师为顾客理发();}}customer()//顾客进程{P(mutex);//开始操作临界资源if(waiting<n)//判断是否有空座,按老师给的题目,座位数为n{waiting++;//等候的人数加1V(customers);//来了一个顾客V(mutex);//开放临界资源P(barbers);//等理发师来理发,之后表明理发师忙碌顾客接受理发师理发();}else//若没有空座,直接走人,并开放临界资源V(mutex);}利用整型信号量解决和尚打水问题semaphore mutex1=1,mutex2=1;//分别为操作“井”和“水缸”这两个临界资源的信号量semaphore count=3;//操作临界资源“水桶”的信号量,表明可用水桶的数目semaphore empty=10,full=0;//水缸满和空的信号量young()//小和尚进程{while(1){P(empty);//判断水缸是否可装水P(count);//是否有可用的水桶,申请使用一个水桶P(mutex1);//操作临界资源“井”小和尚从井中取水();V(mutex1);//开放“井”P(mutex2);//操作临界资源“水缸”小和尚把水倒入水缸();V(mutex2);//开放“水缸”V(count);//归还一个水桶V(full);//表明水缸中已经添加了一桶水}}old()//老和尚进程{while(1){P(full);//判断水缸中是否有水可喝P(mutex2);//操作临界资源“水缸”老和尚从水缸中取水();V(mutex2);//开放“水缸”V(empty);//表明水已经被喝了一桶}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
cout<<"第"<<count<<"个顾客来了"<<endl;
if (waiting<chairs) //如果还有椅子可以坐
{
if (waiting!=0){
cout<<"此时有"<<waiting <<"个人在等待理发"<<endl;
}
else
cout<<"没有人在等待"<<endl; //输出有多少人在等待
cout<<"第"<<finish<<"个顾客理发完毕,离开"<<endl;
}
HANDLE Mutex=CreateMutex(NULL, FALSE, "Mutex"); //用来实现进程的互斥
HANDLE barbers=CreateSemaphore(NULL, 1,1, "barbers");//定义信号量来进行线程间的同步
P(mutex); //进程互斥
waiting := waiting–1; //等候顾客数少一个
V(barbers); //理发师去为一个顾客理发
V(mutex); //开放临界区
cut-hair( ); //正在理发
customer()
P(mutex); //进程互斥
if (waiting)
{ waiting := waiting+1; //等候顾客数加1
ReleaseMutex(Mutex);//释放互斥量,以便其他线程使用
WaitForSingleObject(barbers,INFINITE);//等待理发
gethaircut(); //理发并离开
}
else
{
cout<<"座位已满,第"<<count<<"个顾客离开"<<endl; //没有椅子,顾客直接离开
操作系统课程设计
专业:信息安全
班级:0801
姓名:黄春海
学号:3080604022
老师:薛安荣
一、课程设计的目的与要求
1、课程设计目的
本课程设计的主要目的是通过生产者和消费者问题(理发店问题)的设计和调试,使学生掌握进程同步的工作原理,利用信号量的原理和机制去解决同步问题,并培养学生分析和解决实际问题的能力。
hThread2=CreateThread (NULL,0,barber,NULL,0,NULL); //产生一个理发师进程
while(close_door!='y')
{
Sleep(random); //顾客随机到来
hThread1=CreateThread(NULL,0,customer,NULL,a,NULL);
HANDLE customers=CreateSemaphore(NULL,0,3,"customers");
DWORD WINAPI customer(LPVOID pParm2) //顾客的线程
{
WaitForSingleObject(Mutex ,INFINITE); //p(mutex)进入临界区
PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。
2、涉及的数据结构
程序中引入3个信号量和一个控制变量:
(1)控制变量wait用来记录等候理发的顾客数,初值均为0;
(2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;
三问题实现
1.PV操作代码如下:
int waiting=0;//等候理发的顾客数
int chairs=n;//为顾客准备的椅子数
semaphore customers=0, barbers=0,mutex=1;
barber()
while(TRUE); //理完一人,还有顾客吗?
P(cutomers); //若无顾客,理发师睡眠
系统:Windows XP
语言:C
开发工具:Visual C++ 6.0
四、分析设计
题目中要求描述理发师和顾客的行为,因此需要两类进程Barber ()和Customer()分别描述理发师和顾客的行为。当理发师看报时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师休息,因此理发师和顾客之间是同步的关系,由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。故引入3个信号量和一个控制变量:1)控制变量waiting用来记录等候理发的顾客数,初值均为0;2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;4)信号量mutex用于互斥,初值为1
ReleaseMutex(Mutex);
}arber(LPVOID pParm1) //理发师的线程
{
while(true) //一直执行
{
WaitForSingleObject(customers,INFINITE);//p(customers),等待顾客
customers = 0; barbers= 1;wait = 0; mutex=1;
3、流程图
五、运行示例及结果分析
1、运行示例
六、个人体会
通过这个课设更好的了解操作系统的一些问题融汇平时上课不懂的地方,最终解决了问题。
七、
#include <windows.h>
#include "iostream.h"
waiting++;
cout<<"还有"<<chairs-waiting+1<<"个座位"<<endl;
cout<<"有座位,顾客已经坐下"<<endl;
ReleaseSemaphore(customers,1,NULL);//v(customer) sfangxinghaoliang
ResumeThread(customers);//唤醒理发师进程
2、课程设计要求
(1)、在Windows系统环境下,用Windows API编程实现操作系统经典同步问题。
(2)、理解和运用信号量、PV原语、进程间的同步互斥关系等基本知识。
(3)、在实习过程中,加强对于进程同步概念的理解,对于实验进行分析。
(4)、掌握在Windows环境下多线程(进程)程序设计的一些基本方法。
}
else ;
}
if (close_door=='y')
{
cout<<"********暂停营业!********"<<endl;
return 0;
}
}
WaitForSingleObject(Mutex,INFINITE); //等待互斥量
waiting--; //等待的人数减一
ReleaseSemaphore(barbers,1,NULL); //释放信号量
ResumeThread(barbers); //唤醒顾客进程
ReleaseMutex(Mutex); //v(mutex);
int count(0); //顾客的号码数
int finish(0); //理发完毕的顾客数目
DWORD a;
void cuthair()
{
Sleep (10000);
cout<<"理发完成!"<<endl; //理发师理发函数,用时10秒
}
void gethaircut()
{
Sleep (10001); //顾客被理发的函数,为了和理发师之间有所区别,比理发师理发时间长0.001秒。
二、设计内容
理发店理有一位理发师、一把理发椅和5把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发椅上睡觉。一个顾客到来时,它必须叫醒理发师。如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。
三、开发环境
操作系统功能的模拟实现可以在计算机系统的终端上进行。本次课程设计的主要过程是用语言来模拟操作系统的主要功能。试验环境如下:
cuthair(); //理发
finish++; //理发完毕的顾客数目加一
}
return 0;
}
int main()
{
cout<<"请输入椅子的总数目:";
cin>>chairs;
cout<<"理发店共有"<<chairs<<"把椅子"<<endl;
HANDLE hThread1;
HANDLE hThread2;
信号量
信号量的定义:
信号量(Semaphore)是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用临界区的进程数。
对信号量操作的PV原语:
P原语操作的动作是:
(1)S减1;