📄 simulation.cpp
字号:
//
// FILE: Simulation.cpp
//
// Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring
//
/////////////////////////////////////////////////////////////////////////
#include "Simulation.h"
// CTable constructor...
CTable::CTable() {
m_hwndGUI = NULL;
m_bContinue = TRUE;
}
// CTable member functions...
void CTable::SetHwnd(HWND hwnd) {
m_hwndGUI = hwnd;
}
void CTable::TakeForks(int nId) {
m_cmForks[nId].WaitForTwo( m_cmForks[(nId + 1) % NUMBER_PHILOSOPHERS], TRUE, INFINITE);
// we must update the interface AFTER we acquire the forks...
NotifyParent( WM_DININGSIM_FORK_UPDATE, nId, FORK_STATE_UNAVAILABLE);
NotifyParent( WM_DININGSIM_FORK_UPDATE, (nId + 1) % NUMBER_PHILOSOPHERS, FORK_STATE_UNAVAILABLE);
}
void CTable::DropForks(int nId) {
// we must update the interface just BEFORE we release the forks...
NotifyParent( WM_DININGSIM_FORK_UPDATE, nId, FORK_STATE_AVAILABLE);
NotifyParent( WM_DININGSIM_FORK_UPDATE, (nId + 1) % NUMBER_PHILOSOPHERS, FORK_STATE_AVAILABLE);
m_cmForks[nId].Release();
m_cmForks[(nId + 1) % NUMBER_PHILOSOPHERS].Release();
}
BOOL CTable::Continue(void) {
return m_bContinue;
}
void CTable::Stop(void) {
m_bContinue = FALSE;
}
void CTable::Run(void) {
m_bContinue = TRUE;
}
void CTable::NotifyParent( UINT uMsg, WPARAM wParam, LPARAM lParam) {
// this is a post to make sure that the philosopher thread runs
// asynchronously with the GUI,,,
::PostMessage( m_hwndGUI, uMsg, wParam, lParam);
}
// CPhilosopher constructor...
CPhilosopher::CPhilosopher( int nId, CTable *pt) : m_nId(nId), m_pTable(pt) {
return;
}
// CPhilosopher member functions...
unsigned CPhilosopher::ThreadHandlerProc(void) {
Philosophize();
return 0;
}
void CPhilosopher::Philosophize(void) {
// main philosopher Eat/Think loop,..
while (m_pTable->Continue()) {
// update the GUI that this philosopher is hungry...
m_pTable->NotifyParent( WM_DININGSIM_PHILOSOPHER_UPDATE, m_nId, PHILOSOPHER_STATE_HUNGRY);
m_pTable->TakeForks(m_nId);
// update the GUI that this philosopher is eating...
m_pTable->NotifyParent( WM_DININGSIM_PHILOSOPHER_UPDATE, m_nId, PHILOSOPHER_STATE_EATING);
Eat();
m_pTable->DropForks(m_nId);
// update the GUI that this philosopher is thinking...
m_pTable->NotifyParent( WM_DININGSIM_PHILOSOPHER_UPDATE, m_nId, PHILOSOPHER_STATE_THINKING);
Think();
}
}
void CPhilosopher::Think(void) {
// think for a random period of time...
Sleep((rand() % (MAXIMUM_THINKING_TIME - MINIMUM_THINKING_TIME)) + MINIMUM_THINKING_TIME);
}
void CPhilosopher::Eat(void) {
// think for a random period of time...
Sleep((rand() % (MAXIMUM_EATING_TIME - MINIMUM_EATING_TIME)) + MINIMUM_EATING_TIME);
}
// CPhilosopherThread constuctor creates the worker thread with the
// passed in thread handler...
CPhilosopherThread::CPhilosopherThread( CPhilosopher *pPhilosopher) : CMcl4MfcWorkerThread(pPhilosopher) {
m_pPhilosopher = pPhilosopher;
}
// CPhilosopherThread destructor cleans up the thread handler...
CPhilosopherThread::~CPhilosopherThread() {
delete m_pPhilosopher;
}
// CPhilosopherThread pseudo-virtual constructor...
CPhilosopherThread *CPhilosopherThread::CreatePhilosopher( int nId, CTable *pt) {
CPhilosopher *pPhilosopher = new CPhilosopher( nId,pt);
return new CPhilosopherThread(pPhilosopher);
}
// CSimulation member functions...
void CSimulation::SetHwnd(HWND hwnd) {
// pass the HWND to the table object, which does the
// actual posting of the messages...
m_table.SetHwnd(hwnd);
}
void CSimulation::Run(void) {
// put the table in the run state...
m_table.Run();
// create the philosophers and start them running...
for (int i = 0; i < NUMBER_PHILOSOPHERS; i++) {
m_cPhilosophers[i] = CPhilosopherThread::CreatePhilosopher( i, &m_table);
}
}
void CSimulation::Stop(void) {
// add the philsopher threads to a collection.,.
CMclWaitableCollection collection;
for (int i = 0; i < NUMBER_PHILOSOPHERS; i++) {
collection.AddObject(*m_cPhilosophers[i]);
}
// tell the philosopher threads to exit...
m_table.Stop();
// wait until all the threads have terminated...
collection.Wait( TRUE, INFINITE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -