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

📄 ceventdemo.cpp

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

// global variables to store event objects shared
// between the primary and child threads
// we pass FALSE in the constructor to create an
// auto-reset event, and TRUE to create a
// manual-reset event...
CMclEvent g_cAutoResetEvent(FALSE);
CMclEvent g_cManualResetEvent(TRUE);

// procedure for child threads...
unsigned __stdcall ThreadStartFunc( void *lpThreadParameterId) {
    DWORD dwStatus;

    // inform the user that thread has started...
    printf("Thread #%d id=0x%08x, started.\n",
            (int) lpThreadParameterId,
            GetCurrentThreadId());

    // wait for the auto-reset event...
    printf("Thread #%d id=0x%08x, waiting for auto-reset event.\n",
            (int) lpThreadParameterId,
            GetCurrentThreadId());
    
    dwStatus = g_cAutoResetEvent.Wait(INFINITE);

    if (dwStatus == WAIT_OBJECT_0) {
        printf("Thread #%d id=0x%08x, wait for auto-reset event succeeded.\n",
                (int) lpThreadParameterId,
                GetCurrentThreadId());
    }
    else {
        printf("Thread #%d id=0x%08x, wait for auto-reset event failed.\n",
                (int) lpThreadParameterId,
                GetCurrentThreadId());
        return 1;
    }

    // wait for the manual-reset event...
    printf("Thread #%d id=0x%08x, waiting for manual-reset event.\n",
            (int) lpThreadParameterId,
            GetCurrentThreadId());    
    
    dwStatus = g_cManualResetEvent.Wait(INFINITE);

    if (dwStatus == WAIT_OBJECT_0) {
        printf("Thread #%d id=0x%08x, wait for manual-reset event succeeded.\n",
                (int) lpThreadParameterId,
                GetCurrentThreadId());
    }
    else {
        printf("Thread #%d id=0x%08x, wait for manual-reset event failed.\n",
                (int) lpThreadParameterId,
                GetCurrentThreadId());
        return 2;
    }

    // exit...
    printf("Thread #%d id=0x%08x, exiting.\n", 
            (int) lpThreadParameterId,
            GetCurrentThreadId());
    return 0;
}

int main(void) {
    DWORD dwStatus;
    BOOL bStatus;
    HANDLE ahThreads[2];
    DWORD dwThreadID1;
    DWORD dwThreadID2;

    // the auto and manual reset events have been 
    // already been created by the constructors for the 
    // g_cAutoResetEvent and g_cManualResetEvent global objects...

    // create first child thread...
    ahThreads[0] = (HANDLE) _beginthreadex(NULL, 0, ThreadStartFunc, (void*) 1, 0, (unsigned *)&dwThreadID1);
    if (ahThreads[0]) {
        printf("Primary thread created child thread #1 with id=0x%08x.\n", dwThreadID1);
    }
    else {
        printf("Primary thread unable to create child thread #1.\n");
        exit(-3);
    }

    // create second child thread...
    ahThreads[1] = (HANDLE) _beginthreadex(NULL, 0, ThreadStartFunc, (void*) 2, 0, (unsigned *)&dwThreadID2);
    if (ahThreads[1]) {
        printf("Primary thread created child thread #2 with id=0x%08x.\n", dwThreadID2);
    }
    else {
        printf("Primary thread unable to create child thread #2.\n");
        exit(-4);
    }

    // give the child threads a chance to start before we signal the events...
    // this isn't required for the program to behave properly but it gives
    // the second child thread an equal chance to react to the first signaling of
    // the auto-reset event...
    Sleep(1000);

    // signal auto-reset event...
    printf("Primary thread signaling auto-reset event.\n");
    bStatus = g_cAutoResetEvent.Set();
    if (!bStatus) {
        printf("Unable to signal auto-reset event.\n");
        exit(-5);
    }

    // signal manual-reset event...
    printf("Primary thread signaling manual-reset event.\n");
    bStatus = g_cManualResetEvent.Set();
    if (!bStatus) {
        printf("Unable to signal manual-reset event.\n");
        exit(-6);
    }

    // wait for one child thread to exit...
    printf("Primary thread waiting for one of the child threads to exit.\n");
    dwStatus = WaitForMultipleObjects( 2, ahThreads, FALSE, INFINITE);
    if ((dwStatus == WAIT_OBJECT_0) || (dwStatus == WAIT_OBJECT_0 + 1)) {
        printf("Wait for one child thread to exit succeeded.\n");
    }
    else {
        printf("Wait for one child thread to exit failed.\n");
        exit(-7);
    }

    // signal auto-reset event again...
    printf("Primary thread signaling auto-reset event again.\n");
    bStatus = g_cAutoResetEvent.Set();
    if (!bStatus) {
        printf("Unable to signal auto-reset event again.\n");
        exit(-8);
    }

    // wait for both threads to exit...
    printf("Primary thread waiting for both child threads to exit.\n");
    dwStatus = WaitForMultipleObjects( 2, ahThreads, TRUE, INFINITE);
    if (dwStatus == WAIT_OBJECT_0) {
        printf("Wait for both child threads to exit succeeded.\n");
    }
    else {
        printf("Wait for both child threads to exit failed.\n");
        exit(-9);
    }

    // clean up...
    CloseHandle(ahThreads[0]);
    CloseHandle(ahThreads[1]);

    // no need to clean up event objects, the
    // destructors will di it automatically when the
    // global event objects are destroyed...

    // exiting...
    printf("Primary thread exiting.\n");
    return 0;
}

⌨️ 快捷键说明

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