Sleeping Barber Window版本实现
来源:互联网 发布:网络商品交易改革 编辑:程序博客网 时间:2024/05/16 10:29
介绍:
题目来自于开源力量(www.osforce.cn) C语言进阶课程
具体如下:
一间理发店有3位理发师,理发店有沙发,最多坐10人。
3个理发师是三个线程,没有客人时,理发师睡觉。客人上门时,理发师醒过来服务客人。如果理发师都在忙,客人则坐到沙发上等待,如果沙发满了,客人直接离开。
收到关门信号的时候,沙发上的客人直接离开,对于服务到一半的客人,理发师要帮他们剪完头发。
总共两个进程,一个是理发店的,另一个用于发送客人上门和关门命令。
负责发送命令的进程:
界面如下:
事件初始化代码:
//事件名称const wchar_t szCustomerComeEvent[] = L"szCustomerComeEvent";const wchar_t szCloseShopEvent[] = L"szCloseShopEvent";CbarberShopDlg::CbarberShopDlg(CWnd* pParent /*=NULL*/): CDialogEx(CbarberShopDlg::IDD, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); //在对话框类的构造函数中创建事件 m_customerComeEvent = ::CreateEvent(NULL,TRUE,FALSE,szCustomerComeEvent); m_closeShopEvent = ::CreateEvent(NULL,TRUE,FALSE,szCloseShopEvent);}
事件触发代码:
//客人上门void CbarberShopDlg::OnBnClickedCustomerComeButton(){ ::SetEvent(m_customerComeEvent); ::ResetEvent(m_closeShopEvent);}//理发店关门void CbarberShopDlg::OnBnClickedCloseButton(){ ::SetEvent(m_closeShopEvent); ::ResetEvent(m_customerComeEvent);}
对话框结束清理事件:
CbarberShopDlg::~CbarberShopDlg(){ //关闭事件 CloseHandle(m_customerComeEvent); CloseHandle(m_closeShopEvent);}
理发师实现进程:
//理发师的数量const int BARBER_COUNT = 3;//沙发的容量const int SOFA_CONTAIN_COUNT = 10;//客人上门的事件名称const wchar_t szCustomerComeEvent[] = L"szCustomerComeEvent";//理发店关门的事件名称const wchar_t szCloseShopEvent[] = L"szCloseShopEvent";//信号量的名称const wchar_t szSemaphoreName[] = L"szSemaphoreName";//沙发int SOFA[SOFA_CONTAIN_COUNT];//客人上门事件的句柄HANDLE g_customerComeEvent = 0;//理发店关门事件的句柄HANDLE g_closeShopEvent = 0;//信号量句柄HANDLE g_semphore = 0;//保护沙发的临界区变量CRITICAL_SECTION g_sofaSection;DWORD WINAPI BarberProc( LPVOID lpParameter){ //获取线程的id int barberId = *((int*)lpParameter); //等待客人上门,延时0 if(WAIT_TIMEOUT==::WaitForSingleObject(g_customerComeEvent,0)) { //客人没有上门,打印 理发师正在睡觉 printf("barber %d is sleeping \n",barberId); //等待客人上门,永久 ::WaitForSingleObject(g_customerComeEvent,INFINITE); } HANDLE handles[2] = {g_closeShopEvent,g_semphore}; while(true) { //等待关门事件或者客人坐到沙发上 DWORD result = ::WaitForMultipleObjects(2,handles,FALSE,INFINITE); //信号量 if((WAIT_OBJECT_0+1)==result) { //从沙发里面取出一个客户 ::EnterCriticalSection(&g_sofaSection); int customerId = SOFA[0]; assert(customerId>0); memcpy(SOFA,SOFA+1,(SOFA_CONTAIN_COUNT-1)*sizeof(SOFA[0])); SOFA[SOFA_CONTAIN_COUNT-1]=0; ::LeaveCriticalSection(&g_sofaSection); printf("barber %d is working on customer %d \n",barberId,customerId); Sleep(4000); } //关门信号 else if((WAIT_OBJECT_0)==result) { printf("barber %d is after work\n",barberId); return 0; } else { assert(false); return 0; } } return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){ //初始化沙发 memset(SOFA,0,sizeof(SOFA)); //初始化临界区 ::InitializeCriticalSection(&g_sofaSection); //创建信号量 g_semphore=::CreateSemaphore(NULL,0,SOFA_CONTAIN_COUNT,szSemaphoreName); if(0==g_semphore) { goto EXIT; } //创建事件 g_customerComeEvent = ::CreateEvent(NULL,TRUE,FALSE,szCustomerComeEvent); if(0==g_customerComeEvent) { goto EXIT; } g_closeShopEvent = ::CreateEvent(NULL,TRUE,FALSE,szCloseShopEvent); if(0==g_closeShopEvent) { goto EXIT; } //创建理发师线程 HANDLE barberThread[BARBER_COUNT] ={0}; int barberId[BARBER_COUNT]={0}; DWORD dword; for(int i=0;i<BARBER_COUNT;++i) { barberId[i] = i+1; barberThread[i] = ::CreateThread(NULL,0,BarberProc,&barberId[i],0,&dword); if(0==barberThread[i]) { goto EXIT; } } HANDLE h[2]={g_closeShopEvent,g_customerComeEvent}; int customerId = 1; while(true) { DWORD result = ::WaitForMultipleObjects(2,h,FALSE,INFINITE); //客人上门 if((WAIT_OBJECT_0+1)==result) { //检查沙发是否已满 if(0!=SOFA[SOFA_CONTAIN_COUNT-1]) { //满 让客人自己离开 printf("sofa is full \n"); printf("customer %d is leaving \n",customerId); } else { //未满 将客人放入沙发 ::EnterCriticalSection(&g_sofaSection); for(int i=0;i<SOFA_CONTAIN_COUNT;++i) { if(0==SOFA[i]) { SOFA[i] = customerId; printf("customer %d is sitting on the sofa \n",customerId); break; } } ::LeaveCriticalSection(&g_sofaSection); long previousNum = 0; // ::ReleaseSemaphore(g_semphore,1,&previousNum); } Sleep(1000); customerId++; } //关门 else if((WAIT_OBJECT_0)==result) { printf("the shop is going to close \n"); ::EnterCriticalSection(&g_sofaSection); for(int i=0;i<SOFA_CONTAIN_COUNT;++i) { if(0!=SOFA[i]) { printf("customer %d is leaving \n",SOFA[i]); SOFA[i] = 0; } } ::LeaveCriticalSection(&g_sofaSection); //等待理发师线程的结束 ::WaitForMultipleObjects(BARBER_COUNT,barberThread,TRUE,INFINITE); //跳出循环 break; } else { assert(false); goto EXIT; } } //善后及异常处理:EXIT: //删除临界区 DeleteCriticalSection(&g_sofaSection); //关闭事件 CloseHandle(g_customerComeEvent); g_customerComeEvent = 0; CloseHandle(g_closeShopEvent); g_closeShopEvent = 0; //关闭信号量 CloseHandle(g_semphore); g_semphore = 0; //关闭线程 for(int i=0;i<BARBER_COUNT;++i) { CloseHandle(barberThread[i]); barberThread[i] = 0; } return 0;}
运行结果:
客人未上门:
收到关门指令:
0 0
- Sleeping Barber Window版本实现
- 操作系统实验,IPC(一):sleeping barber,睡眠理发师问题
- barber
- Sleeping
- Sleeping
- Window版本
- Go Go Sleeping!Sleeping!
- barber event 设计
- HDU3905 Sleeping
- 检测window版本
- vc获取window版本
- redis window版本
- window版本的生日快乐
- window的版本宏
- baber main thread barber thread
- c语言之ls目录的简单实现和window版本dirent.h
- Window OpenGL 程序C++版本
- window下node版本管理
- Spring和MyBatis环境整合
- sed命令总结
- hdu3280 Golden Eggs(网络流最小割)
- 一起talk C栗子吧(第十九回:C语言实例--位操作)
- Saving HDU(2111)
- Sleeping Barber Window版本实现
- nginx压力测试及防止恶意压力测试的方法
- python 实现DES加密 ECB模式
- spring mvc + jpa 学习
- ACboy needs your help again!(1702)
- Delphi 遍历所有目录和子目录下的文件名(可按后缀名遍历)
- Spring RequestMapping 注解介绍
- APNS推送
- android gson解析Json,Could not find class 'com.google.gson.Gson'