[关闭]
@1405010304geshuaishuai 2016-05-13T09:37:25.000000Z 字数 2577 阅读 541

实验六 理发师通信

理发师通信


1、实验目的

通过生产者和消费者问题(理发店问题)的设计和调试,使学生掌握进程同步的工作原理,利用信号量的原理和机制去解决同步问题。

2、实验内容

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

3、流程图

liucheng1
图 6-1 barber 进程
liucheng2
图 6-2 customer 进程

4、实验内容和步骤

题目中要求描述理发师和顾客的行为,因此需要两类进程Barber()和Customer()分别描述理发师和顾客的行为。当理发师看报时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师休息,因此理发师和顾客之间是同步的关系,由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。故引入3个信号量和一个控制变量:1)控制变量waiting用来记录等候理发的顾客数,初值均为0;2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;4)信号量mutex用于互斥,初值为1

4.实验源代码

  1. #include<windows.h>
  2. #include "iostream.h"
  3. #include "math.h"
  4. #define random (rand()*10000)/RAND_MAX //定义一个随机函数来产生顾客,并且使两个顾客间的时间少于10秒
  5. int long waiting(0); //正在等待的顾客的数目
  6. int chairs; //椅子的总数目
  7. char close_door; //关门
  8. int count(0); //顾客的号码数
  9. int finish(0); //理发完毕的顾客数目
  10. DWORD a;
  11. void cutchair()
  12. {
  13. Sleep(10000);
  14. cout<<"理发完成!"<<endl; //理发师理发函数,用时10秒
  15. }
  16. void gethaircut()
  17. {
  18. Sleep(10001); //顾客被理发的函数
  19. cout<<"第"<<finish<<"个顾客理发完毕,离开"<<endl;
  20. }
  21. HANDLE Mutex=CreateMutex(NULL,FALSE,"Mutex"); //用来实现进程的互斥
  22. HANDLE barbers=CreateSemaphore(NULL,1,1,"barbers"); //定义信号量来进行线程间的同步
  23. HANDLE customers=CreateSemaphore(NULL,0,3,"customers");
  24. DWORD WINAPI customer(LPVOID pParm2) //顾客的线程
  25. {
  26. WaitForSingleObject(Mutex,INFINITE); //p(mutex)进入临近区
  27. count++; //来的是第几名顾客
  28. cout<<"第"<<count<<"个顾客来了"<<endl;
  29. if(waiting<chairs) //如果还有椅子可以坐
  30. {
  31. if(waiting!=0){
  32. cout<<"此时有"<<waiting<<"个人在等待理发"<<endl;
  33. }
  34. else
  35. cout<<"没有人在等待"<<endl;//输出有多少人在等待
  36. waiting++;
  37. cout<<"还有"<<chairs-waiting+1<<"个座位"<<endl;
  38. cout<<"有座位,顾客已经坐下"<<endl;
  39. ReleaseSemaphore(customers,1,NULL); //释放信号量
  40. ResumeThread(customers); //唤醒理发师进程
  41. ReleaseMutex(Mutex); //释放互斥量,以便其他线程使用
  42. WaitForSingleObject(barbers,INFINITE); //等待理发
  43. gethaircut(); //理发并离开
  44. }
  45. else
  46. {
  47. cout<<"座位已满,第"<<count<<"个顾客离开"<<endl; //没有椅子,顾客直接离开
  48. ReleaseMutex(Mutex);
  49. }
  50. return 0;
  51. }
  52. DWORD WINAPI barber(LPVOID pPam1) //理发师线程
  53. {
  54. while(true) //一直执行
  55. {
  56. WaitForSingleObject(customers,INFINITE); //p(customers),等待顾客
  57. WaitForSingleObject(Mutex,INFINITE); //等待互斥量
  58. waiting--;//等待的人数减一
  59. ReleaseSemaphore(barbers,1,NULL); //释放信号量
  60. ResumeThread(barbers);//唤醒顾客进程
  61. ReleaseMutex(Mutex); //v(mutex)
  62. cutchair();//理发
  63. finish++; //理发完毕的顾客数目加一
  64. }
  65. return 0;
  66. }
  67. int main()
  68. {
  69. cout<<"请输入椅子的总数目:";
  70. cin>>chairs;
  71. cout<<"理发店共有"<<chairs<<"把椅子"<<endl;
  72. HANDLE hThread1;
  73. HANDLE hThread2;
  74. hThread2=CreateThread(NULL,0,barber,NULL,0,NULL); //产生一个理发师进程
  75. while(close_door!='y')
  76. {
  77. Sleep(random);//顾客随机到来
  78. hThread1=CreateThread(NULL,0,customer,NULL,a,NULL);
  79. cout<<endl<<"**********欢迎光临**********"<<endl;
  80. if(finish>=10&&waiting==0)//如果完成数超过10并且没有人等待
  81. {
  82. cout<<"已经为"<<finish<<"个顾客理发了,要关门下班吗?"<<endl;
  83. cin>>close_door;
  84. return close_door;
  85. }
  86. }
  87. if(close_door=='y')
  88. {
  89. cout<<"**********暂停营业*********"<<endl;
  90. return 0;
  91. }
  92. }

5.实验截图

实验截图如图6-3:
result1
图 6-3 运行结果

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注