PoEdu培训 Windows班 第三十六课 Windows 内核对象(三) 事件内核对象
文章类别: 培训笔记 0 评论

PoEdu培训 Windows班 第三十六课 Windows 内核对象(三) 事件内核对象

文章类别: 培训笔记 0 评论

Windows 内核对象(三) 事件内核对象

线程的执行顺序需求

有时候我们可能希望B线程等到A线程之后进行执行
我们看下面的例子

#include <Windows.h>
#include <process.h>
#include <tchar.h>

INT* g_pnNum;
BOOL g_bRuning = FALSE;

VOID Entry()
{
    while (InterlockedExchange((LONG*)&g_bRuning, TRUE) == TRUE)
    {
        Sleep(0);
    }
}

VOID Leave()
{
    InterlockedExchange((LONG*)&g_bRuning, FALSE);
}

VOID ThreadPrint(TCHAR* szText)
{
    Entry();
    _tprintf(szText);
    Leave();
}

UINT WINAPI StartThread(LPVOID lParam)
{
    ThreadPrint(TEXT("StartThread is begin....\n"));
    g_pnNum = new INT(0);
    Sleep(1000); 
    ThreadPrint(TEXT("StartThread is end....\n"));
    return 0;
}

UINT WINAPI EndThread(LPVOID lParam)
{
    ThreadPrint(TEXT("EndThread is begin....\n"));
    HANDLE hStart = (HANDLE)lParam;
    ThreadPrint(TEXT("EndThread is waiting....\n"));
    WaitForSingleObject(hStart, INFINITE);
    ThreadPrint(TEXT("EndThread is end waiting....\n"));
    delete g_pnNum;
    ThreadPrint(TEXT("EndThread is end....\n"));
    return 0;
}

INT _tmain()
{
    HANDLE hStart = (HANDLE)_beginthreadex(NULL, 0, StartThread, NULL, 0, NULL);
    HANDLE hEnd = (HANDLE)_beginthreadex(NULL, 0, EndThread, hStart, 0, NULL);
    WaitForSingleObject(hEnd, INFINITE);
    CloseHandle(hStart);
    CloseHandle(hEnd);
    return 0;
}

事件内核对象

事件内核对象多用于来进行同步
它并没有代表系统中任何一个实体
它是为了编程人员使用方便而存在的

创建事件内核对象

CreateEvent

HANDLE WINAPI CreateEvent(
  _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
  _In_     BOOL                  bManualReset,
  _In_     BOOL                  bInitialState,
  _In_opt_ LPCTSTR               lpName
);
#include <Windows.h>

INT _tmain()
{
    // 创建事件内核对象
    HANDLE hEventManualRest = CreateEvent(NULL, TRUE, TRUE, TEXT("HadesEventManualRest"));
    // 当前的事件内核对象是Signal状态, 所以下面的一句Wait不会阻塞
    WaitForSingleObject(hEventManualRest, INFINITE);
    // WaitForSingleObject会改变事件内核对象的信号状态
    // 但是下面一句话并没有阻塞
    // 因为我们的 事件内核对象 是手动更改信号状态
    // 我们需要调用 ResetEvent 让Signal变为无信号
    ResetEvent(hEventManualRest);
    // 经过ResetEvent, 就会阻塞了
    WaitForSingleObject(hEventManualRest, INFINITE);
    CloseHandle(hEventManualRest);

    // 创建事件内核对象
    HANDLE hEventAutoRest = CreateEvent(NULL, TRUE, TRUE, TEXT("HadesEventAutoRest"));
    // 当前的事件内核对象是Signal状态, 所以下面的一句Wait不会阻塞
    WaitForSingleObject(hEventAutoRest, INFINITE);
    // WaitForSingleObject会改变事件内核对象的信号状态
    // 下面一句代码会阻塞
    WaitForSingleObject(hEventManualRest, INFINITE);
    CloseHandle(hEventAutoRest);

    return 0;
}

CreateEventEx

HANDLE WINAPI CreateEventEx(
  _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
  _In_opt_ LPCTSTR               lpName,
  _In_     DWORD                 dwFlags,
  _In_     DWORD                 dwDesiredAccess
);

未完待续...

如有错误,请提出指正!谢谢.

回复