多线程经典问题-----乘客做公交车问题解答1
2013-12-01 18:47
183 查看
1.问题描述:
//车辆行驶问题,司机,乘客售票员协同工作
//司机:开车,停车
//售票员:打开车门,关闭车门
//乘客:上车,下车
解答1:
通过使用CEvent 事件类,模拟三者协同工作。下面的程序只模拟了乘客上车的情况。没有考虑乘客下车。
主程序如下:
各个人员(线程)的业务逻辑如下:
输出结果如下:
//车辆行驶问题,司机,乘客售票员协同工作
//司机:开车,停车
//售票员:打开车门,关闭车门
//乘客:上车,下车
解答1:
通过使用CEvent 事件类,模拟三者协同工作。下面的程序只模拟了乘客上车的情况。没有考虑乘客下车。
主程序如下:
#define PASSENGERCOUNT 20 class CPassengerBusQuestion { public: CPassengerBusQuestion(void); virtual ~CPassengerBusQuestion(void); private: CCriticalSection m_cs; public: CWinThread *m_pDriverThread; CWinThread *m_pConductorThread; CWinThread *m_pPassengerThreadArr[PASSENGERCOUNT]; HANDLE m_eventBusStop; HANDLE m_eventConductorClosedoor; HANDLE m_eventConductorOpenDoor; int m_nTotalStation; int m_nCurStationIndex; public: void Init(); static UINT Driver_Proc(LPVOID lpParam); static UINT Conductor_Proc(LPVOID lpParam); static UINT Passenger_Proc(LPVOID lpParam); private: void OutputLog(char *format,...); };
static char StationName[7][20] = { "车站1", "车站2", "车站3", "车站4", "车站5", "车站6", }; typedef struct tagThreadParam { CPassengerBusQuestion *pBusQuestion; int index;// Passenger NO. int nGetOnStation;//The tation NO Passenger gets on. BOOL bLastPerson;//if Passenger is the Last Person }ThreadParam; void CPassengerBusQuestion::Init() { m_nTotalStation = 4; m_nCurStationIndex = -1; m_pDriverThread = NULL; m_pConductorThread = NULL; m_eventConductorOpenDoor = NULL; m_eventConductorClosedoor = NULL; m_eventBusStop = NULL; m_eventBusStop = ::CreateEvent(NULL,FALSE,FALSE,NULL); m_eventConductorClosedoor = ::CreateEvent(NULL,FALSE,FALSE,NULL); m_eventConductorOpenDoor = ::CreateEvent(NULL,TRUE,FALSE,NULL); m_pDriverThread = AfxBeginThread(CPassengerBusQuestion::Driver_Proc,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); m_pConductorThread = AfxBeginThread(CPassengerBusQuestion::Conductor_Proc,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); for(int i =0;i< PASSENGERCOUNT;i++) { ThreadParam* pParam =new ThreadParam; pParam->pBusQuestion = this; pParam->index = i; pParam->nGetOnStation = i%5; m_pPassengerThreadArr[i] = AfxBeginThread(CPassengerBusQuestion::Passenger_Proc,pParam,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); } m_pDriverThread->ResumeThread(); m_pConductorThread->ResumeThread(); for(int i =0;i<PASSENGERCOUNT;i++) { m_pPassengerThreadArr[i]->ResumeThread(); } }
各个人员(线程)的业务逻辑如下:
//司机线程 UINT CPassengerBusQuestion::Driver_Proc(LPVOID lpParam) { bool bExitThread=false; CPassengerBusQuestion* pBusQuestion =(CPassengerBusQuestion *)lpParam; while(!bExitThread) { pBusQuestion->OutputLog("司机:车辆开始行驶....\n"); ::Sleep(5000); pBusQuestion->OutputLog("司机:到站\n"); pBusQuestion->m_nCurStationIndex++; SetEvent(pBusQuestion->m_eventBusStop); ::WaitForSingleObject(pBusQuestion->m_eventConductorClosedoor,INFINITE); if( pBusQuestion->m_nCurStationIndex == pBusQuestion->m_nTotalStation) { bExitThread = TRUE; } } return 0; } //售票员线程 UINT CPassengerBusQuestion::Conductor_Proc(LPVOID lpParam) { bool bExitThread = false; CPassengerBusQuestion* pBusQuestion =(CPassengerBusQuestion *)lpParam; while(!bExitThread) { ::WaitForSingleObject(pBusQuestion->m_eventBusStop,INFINITE);//等待司机停车 pBusQuestion->OutputLog("售票员:打开车门\n"); pBusQuestion->OutputLog("售票员:%s到了\n", StationName[pBusQuestion->m_currentStationIndex]); SetEvent(pBusQuestion->m_eventConductorOpenDoor); ::Sleep(3000); //等待乘客上下车。 ::ResetEvent(pBusQuestion->m_eventConductorOpenDoor);//此事件只能手工制,不能自动置,手工也不能交给某一个乘客。 pBusQuestion->OutputLog("售票员:关闭车门\n"); SetEvent(pBusQuestion->m_eventConductorClosedoor); if( pBusQuestion->m_nCurStationIndex == pBusQuestion->m_nTotalStation) { bExitThread = TRUE; } } return 0; } //乘客线程 UINT CPassengerBusQuestion::Passenger_Proc(LPVOID lpParam) { ThreadParam* pParam = (ThreadParam *)lpParam; int index = pParam->index; //第几号乘客; int nGetOnStation = pParam->nGetOnStation; //第几站上车 BOOL bLastPerson = pParam->bLastPerson;//是否是最后一个上车的人 CPassengerBusQuestion *pBusQuestion = pParam->pBusQuestion; delete pParam; bool bExitThread = false; while(!bExitThread) { ::WaitForSingleObject(pBusQuestion->m_eventConductorOpenDoor,INFINITE); if(pBusQuestion->m_nCurStationIndex == nGetOnStation)//判断公交车是否到车站了。 { pBusQuestion->OutputLog("乘客%d:在 %s已经上车\n",index,StationName[nGetOnStation]); bExitThread = TRUE; } ::Sleep(1000); } return 0; }
//辅助函数 void CPassengerBusQuestion::OutputLog( char *format,... ) { m_cs.Lock(); char temp[1024]={0}; va_list arg_ptr; va_start(arg_ptr, format); int nWrittenBytes = vsprintf(temp, format, arg_ptr); va_end(arg_ptr); printf(temp); m_cs.Unlock(); }
输出结果如下:
相关文章推荐
- 多线程经典问题-----乘客做公交车问题解答3
- 多线程经典问题-----乘客做公交车问题解答3
- 多线程经典问题-----乘客做公交车问题解答2
- Python多线程经典问题之乘客做公交车算法实例
- 多线程的经典案例(生产消费问题)
- 秒杀多线程第四篇 一个经典的多线程同步问题
- [学习笔记]Java多线程经典问题
- java多线程总结六:经典生产者消费者问题实现
- 秒杀多线程第四篇 一个经典的多线程同步问题
- 16个经典面试问题解答
- 多线程-经典买票问题
- [学习笔记]Java多线程经典问题
- C# 多线程编程 经典模型 哲学家进餐问题
- 秒杀多线程第四篇 一个经典的多线程同步问题
- 秒杀多线程第四篇 一个经典的多线程同步问题
- 秒杀多线程第四篇 一个经典的多线程同步问题
- 秒杀多线程第四篇 一个经典的多线程同步问题
- 局域网经典问题解答
- 多线程第四篇秒杀 一个经典的多线程同步问题
- 秒杀多线程第四篇 一个经典的多线程同步问题