zoukankan      html  css  js  c++  java
  • 使用事件对象

    事件对象:也属于内核对象(mutex属于内核对象),包含以下三个成员
       1> 使用计数
       2> 用于指明该事件是一个自动重置的事件还是一个人工重置的是件的bool值
       3> 用于指明该事件处于已通知状态还是未通知状态的bool值

    使用CreateEvent函数创建事件对象(用一个HANDLE记录)

    使用WaitForSingleObject()/WaitForMultipleObject()函数来等待事件对象变为有信号状态。

    使用SetEvent()将事件对象置为有信号状态,使用ResetEvent()将事件对象置为无信号状态

     

    注释1:对于人工重置的事件对象,需要手动SetEvent和ResetEvent

    注释2:对于自动重置的事件对象,需要手动SetEvent为有信号状态,每次有一个Wait等到它的Thread时,它会自动重置为无信号状态

    #include <windows.h>
    #include
    <stdio.h>

    #define THREADCOUNT 4

    ///事件对象,一个全局写EventObj,4个读EventObj
    HANDLE ghGlobalWriteEvent;
    HANDLE ghReadEvents[THREADCOUNT];

    ///线程响应函数
    DWORD WINAPI ThreadProc(LPVOID);

    void CreateEventsAndThreads(void)
    {
    HANDLE hThread;
    DWORD i, dwThreadID;

    ///创建人工重置、命名的事件对象,初始状态为有信号
    ///此事件对象用于给主线程来阻止4个读线程的读操作
    ghGlobalWriteEvent = CreateEvent(
    NULL,
    // default security attributes
    TRUE, // manual-reset event
    TRUE, // initial state is signaled
    TEXT("WriteEvent") // object name
    );

    if (ghGlobalWriteEvent == NULL)
    {
    printf(
    "CreateEvent failed (%d)\n", GetLastError());
    return;
    }
    ///保证应用程序只有一个实例运行:通过创建一个命名的事件对象
    else if ( GetLastError() == ERROR_ALREADY_EXISTS )
    {
    printf(
    "Named event already exists.\n");
    return;
    }

    // Create multiple threads and an auto-reset event object
    // for each thread. Each thread sets its event object to
    // signaled when it is not reading from the shared buffer.

    for(i = 0; i < THREADCOUNT; i++)
    {
    // Create the auto-reset event
    ///创建自动重置、匿名的事件对象,初始状态为有信号
    ghReadEvents[i] = CreateEvent(
    NULL,
    // no security attributes
    FALSE, // auto-reset event
    TRUE, // initial state is signaled
    NULL); // object not named

    if (ghReadEvents[i] == NULL)
    {
    printf(
    "CreateEvent failed (%d)\n", GetLastError());
    return;
    }

    ///创建Thread,传入各自对应的EventHandle
    hThread = CreateThread(NULL,
    0,
    ThreadProc,
    &ghReadEvents[i], // pass event handle
    0,
    &dwThreadID);

    if (hThread == NULL)
    {
    printf(
    "CreateThread failed (%d)\n", GetLastError());
    return;
    }
    }
    }

    void WriteToBuffer(VOID)
    {
    DWORD dwWaitResult, i;

    ///将ghGlobalWriteEvent重置为无信号状态,用来阻止4个读线程的读操作
    if (! ResetEvent(ghGlobalWriteEvent) )
    {
    printf(
    "ResetEvent failed (%d)\n", GetLastError());
    return;
    }

    ///等待所有的读线程完成read,即ghReadEvents皆变为有信号状态
    dwWaitResult = WaitForMultipleObjects(
    THREADCOUNT,
    // number of handles in array
    ghReadEvents, // array of read-event handles
    TRUE, // wait until all are signaled
    INFINITE); // indefinite wait,无限等待

    switch (dwWaitResult)
    {
    ///所有的read-event对象皆变为有信号状态
    case WAIT_OBJECT_0:
    // TODO: Write to the shared buffer
    printf("Main thread writing to the shared buffer...\n");
    break;

    // An error occurred
    default:
    printf(
    "Wait error: %d\n", GetLastError());
    ExitProcess(
    0);
    }

    ///将ghGlobalWriteEvent事件对象重置为有信号状态
    if (! SetEvent(ghGlobalWriteEvent) )
    {
    printf(
    "SetEvent failed (%d)\n", GetLastError());
    ExitProcess(
    0);
    }

    ///将ghReadEvents事件对象皆重置为有信号状态
    for(i = 0; i < THREADCOUNT; i++)
    if (! SetEvent(ghReadEvents[i]) )
    {
    printf(
    "SetEvent failed (%d)\n", GetLastError());
    return;
    }
    }

    void CloseEvents()
    {
    int i;

    for( i=0; i < THREADCOUNT; i++ )
    CloseHandle(ghReadEvents[i]);

    CloseHandle(ghGlobalWriteEvent);
    }

    void main()
    {
    int i;

    // TODO: Create the shared buffer

    // Create the events and THREADCOUNT threads to read from the buffer

    CreateEventsAndThreads();

    // Write to the buffer three times, just for test purposes

    for(i=0; i < 3; i++)
    WriteToBuffer();

    // Close the events

    CloseEvents();
    }

    DWORD WINAPI ThreadProc(LPVOID lpParam)
    {
    DWORD dwWaitResult;
    HANDLE hEvents[
    2];

    hEvents[
    0] = *(HANDLE*)lpParam; // thread's read event
    hEvents[1] = ghGlobalWriteEvent; // global write event

    ///等待hEvents[0]和hEvents[1]变为有信号状态,也就是ghReadEvents[i]和ghGlobalWriteEvent
    dwWaitResult = WaitForMultipleObjects(
    2, // number of handles in array
    hEvents, // array of event handles
    TRUE, // wait till all are signaled,当所有信号量都变为有信号状态,函数才返回
    INFINITE); // indefinite wait,无限等待

    switch (dwWaitResult)
    {
    // 所有的EventHandle都变为有信号状态
    case WAIT_OBJECT_0:
    // TODO: Read from the shared buffer
    printf("Thread %d reading from buffer...\n",
    GetCurrentThreadId());
    break;

    // An error occurred
    default:
    printf(
    "Wait error: %d\n", GetLastError());
    ExitThread(
    0);
    }

    //重置ghReadEvents[i]为有信号状态,见注释2
    if (! SetEvent(hEvents[0]) )
    {
    printf(
    "SetEvent failed (%d)\n", GetLastError());
    ExitThread(
    0);
    }

    return 1;
    }

  • 相关阅读:
    不可小视视图对效率的影响力
    Maximum Margin Planning
    PhysicsBased Boiling Simulation

    Learning Behavior Styles with Inverse Reinforcement Learning
    Simulating Biped Behaviors from Human Motion Data
    Nearoptimal Character Animation with Continuous Control
    Apprenticeship Learning via Inverse Reinforcement Learning
    回报函数学习的学徒学习综述
    Enabling Realtime Physics Simulation in Future Interactive Entertainment
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/1983837.html
Copyright © 2011-2022 走看看