用信号量解决理发店问题
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int count(0); //顾客的号码数
int finish(0); //理发完毕的顾客数目
DWORD a;
void cuthair()
{
Sleep (10000);
cout<<"理发完成!"<<endl; //理发师理发函数,用时10秒
}
void gethaircut()
{
Sleep (10001); //顾客被理发的函数,为了和理发师之间有所区别,比理发师理发时间长0.001秒。
PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。
2、涉及的数据结构
程序中引入3个信号量和一个控制变量:
(1)控制变量wait用来记录等候理发的顾客数,初值均为0;
(2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;
count++; //来的是第几个顾客
cout<<"第"<<count<<"个顾客来了"<<endl;
if (waiting<chairs) //如果还有椅子可以坐
{
if (waiting!=0){
cout<<"此时有"<<waiting <<"个人在等待理发"<<endl;
}
else
cout<<"没有人在等待"<<endl; //输出有多少人在等待
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)进入临界区
waiting++;
cout<<"还有"<<chairs-waiting+1<<"个座位"<<endl;
cout<<"有座位,顾客已经坐下"<<endl;
ReleaseSemaphore(customers,1,NULL);//v(customer) sfangxinghaoliang
ResumeThread(customers);//唤醒理发师进程
ReleaseMutex(Mutex);//释放互斥量,以便其他线程使用
WaitForSingleObject(barbers,INFINITE);//等待理发
gethaircut(); //理发并离开
}
else
{
cout<<"座位已满,第"<<count<<"个顾客离开"<<endl; //没有椅子,顾客直接离开
cout<<"第"<<finish<<"个顾客理发完毕,离开"<<endl;
}
HANDLE Mutex=CreateMutex(NULL, FALSE, "Mutex"); //用来实现进程的互斥
HANDLE barbers=CreateSemaphore(NULL, 1,1, "barbers");//定义信号量来进行线程间的同步
信号量
信号量的定义:
信号量(Semaphore)是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用临界区的进程数。
对信号量操作的PV原语:
P原语操作的动作是:
(1)S减1;
(2)若S减1后仍大于或等于零,则进程继续执行;
(3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
Vwk.baidu.com语操作的动作是:
(1)S加1;
(2)若相加结果大于零,则进程继续执行;
(3)若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。
cuthair(); //理发
finish++; //理发完毕的顾客数目加一
}
return 0;
}
int main()
{
cout<<"请输入椅子的总数目:";
cin>>chairs;
cout<<"理发店共有"<<chairs<<"把椅子"<<endl;
HANDLE hThread1;
HANDLE hThread2;
三问题实现
1.PV操作代码如下:
int waiting=0;//等候理发的顾客数
int chairs=n;//为顾客准备的椅子数
semaphore customers=0, barbers=0,mutex=1;
barber()
while(TRUE); //理完一人,还有顾客吗?
P(cutomers); //若无顾客,理发师睡眠
}
else ;
}
if (close_door=='y')
{
cout<<"********暂停营业!********"<<endl;
return 0;
}
}
#include "math.h"
#define random (rand()*10000)/RAND_MAX //定义一个随机函数来产生顾客,并且使两个顾客间的时间少于10秒
int long waiting(0); //正在等待的顾客的数目
int chairs; //椅子的总数目
char close_door; //关门
P(mutex); //进程互斥
waiting := waiting–1; //等候顾客数少一个
V(barbers); //理发师去为一个顾客理发
V(mutex); //开放临界区
cut-hair( ); //正在理发
customer()
P(mutex); //进程互斥
if (waiting)
{ waiting := waiting+1; //等候顾客数加1
系统:Windows XP
语言:C
开发工具:Visual C++ 6.0
四、分析设计
题目中要求描述理发师和顾客的行为,因此需要两类进程Barber ()和Customer()分别描述理发师和顾客的行为。当理发师看报时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师休息,因此理发师和顾客之间是同步的关系,由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。故引入3个信号量和一个控制变量:1)控制变量waiting用来记录等候理发的顾客数,初值均为0;2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;4)信号量mutex用于互斥,初值为1
V(customers); //必要的话唤醒理发师
V(mutex); //开放临界区
P(barbers); //无理发师,顾客坐着养神
get-haircut( ); //一个顾客坐下等理/
else
V(mutex); //人满了,走!
2.详细实现:
椅子数目可以设置;程序采用用随机数产生顾客进程,也就是顾客按照随机数自动到来,这样更加接近现实生活;对于理发师,当顾客到来后去理发,如果没有顾客继续看报纸,当理完一个后,判断是否有等待,有则叫下一个来理发,没有的话去看报纸。对于客人,先看理发师是空闲还是忙,空闲则去理发,忙着的话则看是否有位置等待,有则坐下等,没有的话则离开。对于理发时间,是取系统时间来控制,设理发时间为10秒,当两次时间差大于等于10时表示理完叫下一位,小于则继续理发。并且还能控制是否开门营业,当理发师为10个以上顾客理发完成并且没有人在等待时,可以决定是否关门休息.
customers = 0; barbers= 1;wait = 0; mutex=1;
3、流程图
五、运行示例及结果分析
1、运行示例
六、个人体会
通过这个课设更好的了解操作系统的一些问题融汇平时上课不懂的地方,最终解决了问题。
七、
#include <windows.h>
#include "iostream.h"
WaitForSingleObject(Mutex,INFINITE); //等待互斥量
waiting--; //等待的人数减一
ReleaseSemaphore(barbers,1,NULL); //释放信号量
ResumeThread(barbers); //唤醒顾客进程
ReleaseMutex(Mutex); //v(mutex);
cout<<endl<<"********欢迎光临!********"<<endl;
if (finish>=10&&waiting==0) //如果完成数超过10并且没有人等待
{
cout<<"已经为"<<finish<<"个顾客理发了,要关门下班吗?"<<endl;
cin>>close_door;
return close_door;
操作系统课程设计
专业:信息安全
班级:0801
姓名:黄春海
学号:3080604022
老师:薛安荣
一、课程设计的目的与要求
1、课程设计目的
本课程设计的主要目的是通过生产者和消费者问题(理发店问题)的设计和调试,使学生掌握进程同步的工作原理,利用信号量的原理和机制去解决同步问题,并培养学生分析和解决实际问题的能力。
ReleaseMutex(Mutex);
}
return 0;
}
DWORD WINAPI barber(LPVOID pParm1) //理发师的线程
{
while(true) //一直执行
{
WaitForSingleObject(customers,INFINITE);//p(customers),等待顾客
2、课程设计要求
(1)、在Windows系统环境下,用Windows API编程实现操作系统经典同步问题。
(2)、理解和运用信号量、PV原语、进程间的同步互斥关系等基本知识。
(3)、在实习过程中,加强对于进程同步概念的理解,对于实验进行分析。
(4)、掌握在Windows环境下多线程(进程)程序设计的一些基本方法。
(3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为1;
(4)信号量Mutex用于互斥,初值1.
int long wait(0); /*正在等待的顾客的数目*/
int sofas; /*为顾客准备的椅子数*/
customers, barbers,mutex : semaphore;
二、设计内容
理发店理有一位理发师、一把理发椅和5把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发椅上睡觉。一个顾客到来时,它必须叫醒理发师。如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。
三、开发环境
操作系统功能的模拟实现可以在计算机系统的终端上进行。本次课程设计的主要过程是用语言来模拟操作系统的主要功能。试验环境如下:
int finish(0); //理发完毕的顾客数目
DWORD a;
void cuthair()
{
Sleep (10000);
cout<<"理发完成!"<<endl; //理发师理发函数,用时10秒
}
void gethaircut()
{
Sleep (10001); //顾客被理发的函数,为了和理发师之间有所区别,比理发师理发时间长0.001秒。
PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。
2、涉及的数据结构
程序中引入3个信号量和一个控制变量:
(1)控制变量wait用来记录等候理发的顾客数,初值均为0;
(2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;
count++; //来的是第几个顾客
cout<<"第"<<count<<"个顾客来了"<<endl;
if (waiting<chairs) //如果还有椅子可以坐
{
if (waiting!=0){
cout<<"此时有"<<waiting <<"个人在等待理发"<<endl;
}
else
cout<<"没有人在等待"<<endl; //输出有多少人在等待
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)进入临界区
waiting++;
cout<<"还有"<<chairs-waiting+1<<"个座位"<<endl;
cout<<"有座位,顾客已经坐下"<<endl;
ReleaseSemaphore(customers,1,NULL);//v(customer) sfangxinghaoliang
ResumeThread(customers);//唤醒理发师进程
ReleaseMutex(Mutex);//释放互斥量,以便其他线程使用
WaitForSingleObject(barbers,INFINITE);//等待理发
gethaircut(); //理发并离开
}
else
{
cout<<"座位已满,第"<<count<<"个顾客离开"<<endl; //没有椅子,顾客直接离开
cout<<"第"<<finish<<"个顾客理发完毕,离开"<<endl;
}
HANDLE Mutex=CreateMutex(NULL, FALSE, "Mutex"); //用来实现进程的互斥
HANDLE barbers=CreateSemaphore(NULL, 1,1, "barbers");//定义信号量来进行线程间的同步
信号量
信号量的定义:
信号量(Semaphore)是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用临界区的进程数。
对信号量操作的PV原语:
P原语操作的动作是:
(1)S减1;
(2)若S减1后仍大于或等于零,则进程继续执行;
(3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
Vwk.baidu.com语操作的动作是:
(1)S加1;
(2)若相加结果大于零,则进程继续执行;
(3)若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。
cuthair(); //理发
finish++; //理发完毕的顾客数目加一
}
return 0;
}
int main()
{
cout<<"请输入椅子的总数目:";
cin>>chairs;
cout<<"理发店共有"<<chairs<<"把椅子"<<endl;
HANDLE hThread1;
HANDLE hThread2;
三问题实现
1.PV操作代码如下:
int waiting=0;//等候理发的顾客数
int chairs=n;//为顾客准备的椅子数
semaphore customers=0, barbers=0,mutex=1;
barber()
while(TRUE); //理完一人,还有顾客吗?
P(cutomers); //若无顾客,理发师睡眠
}
else ;
}
if (close_door=='y')
{
cout<<"********暂停营业!********"<<endl;
return 0;
}
}
#include "math.h"
#define random (rand()*10000)/RAND_MAX //定义一个随机函数来产生顾客,并且使两个顾客间的时间少于10秒
int long waiting(0); //正在等待的顾客的数目
int chairs; //椅子的总数目
char close_door; //关门
P(mutex); //进程互斥
waiting := waiting–1; //等候顾客数少一个
V(barbers); //理发师去为一个顾客理发
V(mutex); //开放临界区
cut-hair( ); //正在理发
customer()
P(mutex); //进程互斥
if (waiting)
{ waiting := waiting+1; //等候顾客数加1
系统:Windows XP
语言:C
开发工具:Visual C++ 6.0
四、分析设计
题目中要求描述理发师和顾客的行为,因此需要两类进程Barber ()和Customer()分别描述理发师和顾客的行为。当理发师看报时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师休息,因此理发师和顾客之间是同步的关系,由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。故引入3个信号量和一个控制变量:1)控制变量waiting用来记录等候理发的顾客数,初值均为0;2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;4)信号量mutex用于互斥,初值为1
V(customers); //必要的话唤醒理发师
V(mutex); //开放临界区
P(barbers); //无理发师,顾客坐着养神
get-haircut( ); //一个顾客坐下等理/
else
V(mutex); //人满了,走!
2.详细实现:
椅子数目可以设置;程序采用用随机数产生顾客进程,也就是顾客按照随机数自动到来,这样更加接近现实生活;对于理发师,当顾客到来后去理发,如果没有顾客继续看报纸,当理完一个后,判断是否有等待,有则叫下一个来理发,没有的话去看报纸。对于客人,先看理发师是空闲还是忙,空闲则去理发,忙着的话则看是否有位置等待,有则坐下等,没有的话则离开。对于理发时间,是取系统时间来控制,设理发时间为10秒,当两次时间差大于等于10时表示理完叫下一位,小于则继续理发。并且还能控制是否开门营业,当理发师为10个以上顾客理发完成并且没有人在等待时,可以决定是否关门休息.
customers = 0; barbers= 1;wait = 0; mutex=1;
3、流程图
五、运行示例及结果分析
1、运行示例
六、个人体会
通过这个课设更好的了解操作系统的一些问题融汇平时上课不懂的地方,最终解决了问题。
七、
#include <windows.h>
#include "iostream.h"
WaitForSingleObject(Mutex,INFINITE); //等待互斥量
waiting--; //等待的人数减一
ReleaseSemaphore(barbers,1,NULL); //释放信号量
ResumeThread(barbers); //唤醒顾客进程
ReleaseMutex(Mutex); //v(mutex);
cout<<endl<<"********欢迎光临!********"<<endl;
if (finish>=10&&waiting==0) //如果完成数超过10并且没有人等待
{
cout<<"已经为"<<finish<<"个顾客理发了,要关门下班吗?"<<endl;
cin>>close_door;
return close_door;
操作系统课程设计
专业:信息安全
班级:0801
姓名:黄春海
学号:3080604022
老师:薛安荣
一、课程设计的目的与要求
1、课程设计目的
本课程设计的主要目的是通过生产者和消费者问题(理发店问题)的设计和调试,使学生掌握进程同步的工作原理,利用信号量的原理和机制去解决同步问题,并培养学生分析和解决实际问题的能力。
ReleaseMutex(Mutex);
}
return 0;
}
DWORD WINAPI barber(LPVOID pParm1) //理发师的线程
{
while(true) //一直执行
{
WaitForSingleObject(customers,INFINITE);//p(customers),等待顾客
2、课程设计要求
(1)、在Windows系统环境下,用Windows API编程实现操作系统经典同步问题。
(2)、理解和运用信号量、PV原语、进程间的同步互斥关系等基本知识。
(3)、在实习过程中,加强对于进程同步概念的理解,对于实验进行分析。
(4)、掌握在Windows环境下多线程(进程)程序设计的一些基本方法。
(3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为1;
(4)信号量Mutex用于互斥,初值1.
int long wait(0); /*正在等待的顾客的数目*/
int sofas; /*为顾客准备的椅子数*/
customers, barbers,mutex : semaphore;
二、设计内容
理发店理有一位理发师、一把理发椅和5把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发椅上睡觉。一个顾客到来时,它必须叫醒理发师。如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。
三、开发环境
操作系统功能的模拟实现可以在计算机系统的终端上进行。本次课程设计的主要过程是用语言来模拟操作系统的主要功能。试验环境如下: