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

📄 cmclmonitordemo.cpp

📁 window下的多线程编程参考书。值得一读
💻 CPP
字号:
#include <stdio.h>
#include "CMcl.h"

class CFakeSemaphore : private CMclMonitor {
private:
    // internal condition class used to simulate a 
    // semaphore...
    class CFakeSemaphoreCondition : public CMclCondition {
    private:
        LONG m_lMaxCount;
        LONG m_lCurrentCount;

    public:
        CFakeSemaphoreCondition( LONG lMaxCount, LONG lCurrentCount) {
            if (lCurrentCount > lMaxCount)
                lCurrentCount = lMaxCount;

            m_lMaxCount = lMaxCount;
            m_lCurrentCount = lCurrentCount;
        }

        virtual BOOL Condition(void) {
            return (m_lCurrentCount > 0);
        }

        void IncreaseCount(LONG lCounts) {
            m_lCurrentCount += lCounts;
            if (m_lCurrentCount > m_lMaxCount)
                m_lCurrentCount = m_lMaxCount;
        }

        void DecreaseCount(LONG lCounts) {
            m_lCurrentCount -= lCounts;
        }

        LONG GetCount(void) {
            return m_lCurrentCount;
        }
    };

private:
    // declare condition member object...
    CFakeSemaphoreCondition m_cCondition;

public:
    // construct the fake semaphore object and initialize
    // the internal condition object...
    CFakeSemaphore( LONG lMaxCount, LONG lCurrentCount) : 
      m_cCondition( lMaxCount, lCurrentCount) {
          return;
    }

    DWORD Wait( DWORD dwTimeout) {
        // the timeout is ignored...

        // enter the monitor...
        Enter();

        // wait until a count is available...
        WaitForCondition(&m_cCondition);

        // decrease the count...
        m_cCondition.DecreaseCount(1);

        // leave the monitor...
        Leave();

        // return WAIT_OBJECT_0 to simulate a CSemaphore object...
        return WAIT_OBJECT_0;
    }

    BOOL Release( LONG lReleaseCount, LPLONG lpPreviousCount) {
        // enter the monitor...
        Enter();

        // save the current count...
        DWORD nCount = m_cCondition.GetCount();

        // increase the count...
        m_cCondition.IncreaseCount(lReleaseCount);

        // leave the monitor...
        Leave();

        // return the previous count...
        if (lpPreviousCount) 
            *lpPreviousCount = nCount;

        return TRUE;
    }

    DWORD Status(void) {
        return CMclMonitor::Status();
    }
};

unsigned _stdcall ChildThreadProcedure( LPVOID lpcSemaphore) {
    // convert parameter to mutex object pointer...
    CFakeSemaphore *pSemaphore = (CFakeSemaphore *)lpcSemaphore;

    // save this thread's id...
    DWORD dwThreadId = GetCurrentThreadId();

    // repeat three times...
    for (int n =0; n < 3; n++) {
        // wait to acquire the semaphore...
        DWORD dwResult = pSemaphore->Wait(INFINITE);

        if (dwResult == WAIT_OBJECT_0) {
            printf("Thread 0x%08x - acquired the semaphore.\n", dwThreadId);
            // hold the semaphore for one-half second and sleep...
            Sleep(500);

            printf("Thread 0x%08x - releasing the semaphore.\n", dwThreadId);
            LONG lPreviousCount;
            pSemaphore->Release( 1, &lPreviousCount);
            
            // wait for one-half second before trying again...
            Sleep(500);
        }
        else {
            printf("Thread 0x%08x - error calling WaitForSingleObject().\n", dwThreadId);
            return 0xFFFFFFFF;
        }
    }

    return 0;
}

int main(void) {
    HANDLE hChildThread[3];

    // create the fake semaphore...
    CFakeSemaphore cSemaphore( 2, 2);
    if (cSemaphore.Status() != NO_ERROR) {
        printf("Primary thread - error creating semaphore object.\n");
        exit(0xFFFFFFFF);
    }

    // create the child threads...
    unsigned uUnusedThreadId;
    hChildThread[0] = (HANDLE)_beginthreadex( NULL, 0, ChildThreadProcedure, (void*) &cSemaphore, 0, &uUnusedThreadId);
    hChildThread[1] = (HANDLE)_beginthreadex( NULL, 0, ChildThreadProcedure, (void*) &cSemaphore, 0, &uUnusedThreadId);
    hChildThread[2] = (HANDLE)_beginthreadex( NULL, 0, ChildThreadProcedure, (void*) &cSemaphore, 0, &uUnusedThreadId);
    if (!hChildThread[0] || !hChildThread[1] || !hChildThread[2]) {
        printf("Primary thread - error creating child threads.\n");
        exit(0xFFFFFFFF);
    }

    // wait until the child threads have exited...
    DWORD dwResult = WaitForMultipleObjects( 3, hChildThread, TRUE, INFINITE);
    if (dwResult != WAIT_OBJECT_0) {
        printf("Primary thread - error calling WaitForMultipleObjects().\n");
        exit(0xFFFFFFFF);
    }

    // clean up all handles...
    CloseHandle(hChildThread[0]);
    CloseHandle(hChildThread[1]);
    CloseHandle(hChildThread[2]);

    // fake semaphore is cleaned up automatically by the ~CFakeSemaphore destructor...
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -