016 事件内核对象4

示例

#define UNICODE
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <process.h>

#define ___tmainCRTStartup
int *gPNum;
BOOL gUsing = FALSE;

void Entry()
{
    while(InterlockedExchange((long*)&gUsing,TRUE) == TRUE)
    {
        Sleep(0);
    }
}
void Leave()
{
    InterlockedExchange((long*)&gUsing, FALSE);
}

void ThreadPrint(TCHAR* strText)
{
    Entry();
    _tprintf(strText);
    Leave();
}

unsigned __stdcall StartThread(void* lParam)
{
    ThreadPrint("StarThread Beging.......
");
    gPNum = new int(0);
    Sleep(1000);
    ThreadPrint("StarThread End.......
");
    return 0;
}

unsigned __stdcall EndThread(void* lParam)
{
    ThreadPrint("EndThread Beging.......
");
    HANDLE hStart = lParam;
    WaitForSingleObject(hStart, INFINITE);
    delete gPNum;
    ThreadPrint("EndThread End.......
");
    return 0;
}

int main()
{
    HANDLE hStart = (HANDLE)_beginthreadex(nullptr, 0, StartThread, nullptr, 0, nullptr);
    HANDLE hEnd = (HANDLE)_beginthreadex(nullptr, 0, EndThread, hStart, 0 , nullptr);
    WaitForSingleObject(hEnd,INFINITE);
    return 0;
}

无法正常显示

 

使用事件内核对象

  ● CreateEvent

    ○ CreateEvent是一个Windows API函数。它用来创建或打开一个命名的或无名的事件对象。如果想为对象指定一个访问掩码,应当使用CreateEventEx函数。

  ● 函数原型

1 HANDLE WINAPI CreateEvent(
2   _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
3   _In_     BOOL                  bManualReset,
4   _In_     BOOL                  bInitialState,
5   _In_opt_ LPCTSTR               lpName
6 );

  ○ 参数1:lpEventAttributes[输入]

    ○ 一个指向SECURITY_ATTRIBUTES结构的指针,确定返回的句柄是否可被子进程继承。如果lpEventAttributes是NULL,此句柄不能被继承。

  ○ 参数2:bManualReset[输入]

    ○ 指定将事件对象创建成手动复原还是自动复原。如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当一个等待线程被释放以后,系统将会自动将事件状态复原为无信号状态。

  ○ 参数3:bInitialState[输入]

    ○ 指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态。

  ○ 参数4: lpName[输入]

    ○ 指定事件的对象的名称,是一个以0结束的字符串指针。名称的字符格式限定在MAX_PATH之内。名字是对大小写敏感的。

 1 #define UNICODE
 2 #include <stdio.h>
 3 #include <tchar.h>
 4 #include <windows.h>
 5 #include <process.h>
 6 
 7 #define ___tmainCRTStartup
 8 int *gPNum;
 9 BOOL gUsing = FALSE;
10 
11 //事件内核对象
12     //自动重置
13     //手动重置
14 void Entry()
15 {
16     while(InterlockedExchange((long*)&gUsing,TRUE) == TRUE)
17     {
18         Sleep(0);
19     }
20 }
21 void Leave()
22 {
23     InterlockedExchange((long*)&gUsing, FALSE);
24 }
25 
26 void ThreadPrint(TCHAR* strText)
27 {
28     Entry();
29     _tprintf(strText);
30     Leave();
31 }
32 
33 unsigned __stdcall StartThread(void* lParam)
34 {
35     ThreadPrint("StarThread Beging.......
");
36     gPNum = new int(0);
37     Sleep(1000);
38     ThreadPrint("StarThread End.......
");
39     return 0;
40 }
41 
42 unsigned __stdcall EndThread(void* lParam)
43 {
44     ThreadPrint("EndThread Beging.......
");
45     HANDLE hStart = lParam;
46     WaitForSingleObject(hStart, INFINITE);
47     delete gPNum;
48     ThreadPrint("EndThread End.......
");
49     return 0;
50 }
51 
52 int main()
53 {
54     //事件内核对象
55     HANDLE hEvent = CreateEvent(nullptr, TRUE, TRUE, TEXT("MyEvent"));
56                                          // TRUE 手动 
57                                          // FALSE 自动
58     WaitForSingleObject(hEvent,INFINITE);    //等待信号 Single
59     ResetEvent(hEvent);                        //变成NonSingle 变成没有信号的状态
60     HANDLE hStart = (HANDLE)_beginthreadex(nullptr, 0, StartThread, nullptr, 0, nullptr);
61     HANDLE hEnd = (HANDLE)_beginthreadex(nullptr, 0, EndThread, hStart, 0 , nullptr);
62     WaitForSingleObject(hEnd,INFINITE);
63     return 0;
64 }

● CreateEventEx XP 不支持 Windows Vista 支持

● 函数原型

  ○ 权限

    ○ 用户级别权限

    ○ 读权限或者写权限

1 HANDLE WINAPI CreateEventEx(
2 _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
3 _In_opt_ LPCTSTR lpName,
4 _In_ DWORD dwFlags,
5 _In_ DWORD dwDesiredAccess
6 );

  ● lpEventAttributes[in, optional] :
    ○ 一个指向SECURITY_ATTRIBUTES结构的指针,如果该参数设为NULL,那么事件内核对象的句柄不能被子进程继承.
  ● lpName[in, optional] :
    ○ 指向事件内核对象的名称字符串的指针,如果该参数设为NULL,那么这个对象被创建为一个匿名事件内核对象.
  ● dwFlags[in] :
    ○ 这个参数可被设为以下一个或多个值.
      ○ CREATE_EVENT_INITIAL_SET 0x00000002
        ○ 对象初始状态为已触发,否则为未触发.
      ○ CREATE_EVENT_MANUAL_RESET0x00000001
        ○ 这个事件对象必须用ResetEvents函数手动重置,如果不设置这个标志,系统会在内核对象被释放后自动重置.
  ● dwDesiredAccess[in] :
    ○ 访问权限描述标记,详情见Synchronization Object Security and Access Rights[1]

原文地址:https://www.cnblogs.com/sdk123/p/7124346.html