⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simulation.cpp

📁 window下的多线程编程参考书。值得一读
💻 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 + -