📄 newdining.cpp
字号:
#include <stdio.h>
#include <assert.h>
#include "CMcl.h"
enum { NUMBER_PHILOSOPHERS = 5 };
class CTable : public CMclMonitor {
private:
BOOL m_bForkAvailable[NUMBER_PHILOSOPHERS];
BOOL m_bCenterForkAvailable;
BOOL m_bContinue;
public:
CTable() {
int i;
for (i = 0; i < NUMBER_PHILOSOPHERS; i++) {
m_bForkAvailable[i] = TRUE;
}
m_bCenterForkAvailable = TRUE;
m_bContinue = TRUE;
};
BOOL IsLeftForkAvailable(int nId) {
return m_bForkAvailable[nId];
};
BOOL IsRightForkAvailable(int nId) {
return m_bForkAvailable[(nId + 1) % NUMBER_PHILOSOPHERS];
};
BOOL IsCenterForkAvailable(void) {
return m_bCenterForkAvailable;
};
void TakeLeftFork(int nId) {
assert(m_bForkAvailable[nId] == TRUE);
m_bForkAvailable[nId] = FALSE;
};
void TakeRightFork(int nId) {
assert(m_bForkAvailable[(nId + 1) % NUMBER_PHILOSOPHERS] == TRUE);
m_bForkAvailable[(nId + 1) % NUMBER_PHILOSOPHERS] = FALSE;
};
void TakeCenterFork(void) {
assert(m_bCenterForkAvailable);
m_bCenterForkAvailable = FALSE;
};
void DropLeftFork(int nId) {
assert(m_bForkAvailable[nId] == FALSE);
m_bForkAvailable[nId] = TRUE;
};
void DropRightFork(int nId) {
assert(m_bForkAvailable[(nId + 1) % NUMBER_PHILOSOPHERS] == FALSE);
m_bForkAvailable[(nId + 1) % NUMBER_PHILOSOPHERS] = TRUE;
};
void DropCenterFork(void) {
assert(m_bCenterForkAvailable == FALSE);
m_bCenterForkAvailable = TRUE;
};
BOOL CanPhilosopherEat(int nId) {
if (IsLeftForkAvailable(nId) && IsRightForkAvailable(nId))
return TRUE;
else if (IsLeftForkAvailable(nId) && IsCenterForkAvailable())
return TRUE;
else if (IsRightForkAvailable(nId) && IsCenterForkAvailable())
return TRUE;
else
return FALSE;
};
BOOL Continue(void) {
return m_bContinue;
};
void Stop(void) {
m_bContinue = FALSE;
};
};
class ReadyToEat : public CMclCondition {
private:
CTable *m_pTable;
int m_iPhilosopher;
public:
ReadyToEat( CTable *pTable, int iPhilosopher) : CMclCondition() {
m_pTable = pTable;
m_iPhilosopher = iPhilosopher;
};
private:
BOOL Condition(void) {
return (m_pTable->CanPhilosopherEat(m_iPhilosopher));
};
};
class CPhilosopher : public CMclThreadHandler {
private:
int m_nId;
CTable *m_pTable;
ReadyToEat m_ReadyToEat;
BOOL m_bHasLeftFork, m_bHasRightFork, m_bHasCenterFork;
public:
CPhilosopher( int nId, CTable *pt) : m_nId(nId),
m_pTable(pt),
m_ReadyToEat( pt, nId) {
m_bHasLeftFork = m_bHasRightFork = m_bHasCenterFork = FALSE;
return;
};
unsigned ThreadHandlerProc(void) {
Philosophize();
return 0;
}
void TakeForks(void) {
if (m_pTable->IsLeftForkAvailable(m_nId)) {
m_pTable->TakeLeftFork(m_nId);
m_bHasLeftFork = TRUE;
}
if (m_pTable->IsRightForkAvailable(m_nId)) {
m_pTable->TakeRightFork(m_nId);
m_bHasRightFork = TRUE;
}
if (!m_bHasLeftFork || !m_bHasRightFork) {
m_pTable->TakeCenterFork();
m_bHasCenterFork = TRUE;
}
};
void DropForks(void) {
if (m_bHasLeftFork) {
m_pTable->DropLeftFork(m_nId);
m_bHasLeftFork = FALSE;
}
if (m_bHasRightFork) {
m_pTable->DropRightFork(m_nId);
m_bHasRightFork = FALSE;
}
if (m_bHasCenterFork) {
m_pTable->DropCenterFork();
m_bHasCenterFork = FALSE;
}
};
void Philosophize(void) {
while (m_pTable->Continue()) {
m_pTable->Enter();
m_pTable->WaitForCondition(&m_ReadyToEat);
TakeForks();
m_pTable->Leave();
Eat();
m_pTable->Enter();
DropForks();
m_pTable->Leave();
Think();
}
printf( "Philosopher %d is done.\n", m_nId);
};
void Think(void) {
printf( "Philosopher %d Thinking.\n", m_nId);
Sleep(rand() % 100);
};
void Eat(void) {
printf( "Philosopher %d Eating.\n", m_nId);
Sleep(rand() % 100);
};
};
class CPhilosopherThread : public CMclThread {
private:
CPhilosopher *m_pPhilosopher;
private:
CPhilosopherThread( CPhilosopher *pPhilosopher) : CMclThread(pPhilosopher) {
m_pPhilosopher = pPhilosopher;
};
public:
~CPhilosopherThread() {
delete m_pPhilosopher;
};
static CPhilosopherThread *CreatePhilosopher( int nId, CTable *pt) {
CPhilosopher *pPhilosopher = new CPhilosopher( nId,pt);
return new CPhilosopherThread(pPhilosopher);
}
};
int main( int argc, char *argv[]) {
int i;
CTable table;
CMclThreadAutoPtr cPhilosophers[NUMBER_PHILOSOPHERS];
CMclWaitableCollection collection;
for (i = 0; i < NUMBER_PHILOSOPHERS; i++) {
cPhilosophers[i] = CPhilosopherThread::CreatePhilosopher(i, &table);
collection.AddObject(*cPhilosophers[i]);
}
// run for 5 seconds...
Sleep(5000);
table.Stop();
collection.Wait( TRUE, INFINITE);
printf( "All done.\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -