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

📄 newdining.cpp

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