eventdemo.cpp

来自「window下的多线程编程参考书。值得一读」· C++ 代码 · 共 170 行

CPP
170
字号
#include <windows.h>
#include <stdio.h>
#include <process.h>

// global variables to store event handles shared
// between the primary and child threads...
HANDLE g_hAutoResetEvent = NULL;
HANDLE g_hManualResetEvent = NULL;

// 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 = WaitForSingleObject( g_hAutoResetEvent, 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 = WaitForSingleObject( g_hManualResetEvent, 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;

    // create the auto-reset event...
    g_hAutoResetEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
    if (g_hAutoResetEvent) {
        printf("Primary thread created auto-reset event.\n");
    }
    else {
        printf("Primary thread unable to create auto-reset event.\n");
        exit(-1);
    }

    // create the manual-reset event...
    g_hManualResetEvent = CreateEvent( NULL, TRUE, FALSE, NULL);
    if (g_hManualResetEvent) {
        printf("Primary thread created manual-reset event.\n");
    }
    else {
        printf("Primary thread unable to create manual-reset event.\n");
        exit(-2);
    }

    // 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 = SetEvent(g_hAutoResetEvent);
    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 = SetEvent(g_hManualResetEvent);
    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 = SetEvent(g_hAutoResetEvent);
    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]);
    CloseHandle(g_hAutoResetEvent);
    CloseHandle(g_hManualResetEvent);

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

⌨️ 快捷键说明

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