流沙团
CreateEvent 、 SetEvent 、 ResetEvent 的简单测试
2017-12-28 流沙团


CreateEvent 的官方定义如下:



HANDLE WINAPI CreateEvent(

  _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, //安全属性

  _In_     BOOL                  bManualReset, //设置信号复位方式为自动恢复为无信号状态(FALSE)还是手动恢复为无信号状态(TRUE)

  _In_     BOOL                  bInitialState, //初始状态

  _In_opt_ LPCTSTR               lpName  //信号名称,可以为Null

);

方式一:



hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //复位方式为自动恢复到无信号状态,且初始状态为有信号.

此时当使用如下表达式后:

DWORD dReturn = WaitForSingleObject(hEvent, 等待时间);



hEvent 就会变为无信号状态,如果在某个时候再次需要上面的式子成立并通过,则需要使用下面的语句使其变为有信号状态(此方式只能解锁一个等待线程,如需继续解锁,则需要再次使用下面的式子)



SetEvent(hEvent)



方式二:



hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //复位方式为手动恢复到无信号状态,且初始状态为有信号.

此时当使用如下表达式后:

DWORD dReturn = WaitForSingleObject(hEvent, 等待时间);

 

hEvent 就会自动再次变为有信号状态,上面的式子会直接执行并通过(同时有多个等待线程也会直接执行并通过),如果需要将hEvent设置为无信号状态,则需要手动使用下面的语句:



ResetEvent(hEvent);





注:上面的复位方式指的是恢复到无信号状态的方式,若设置为TRUE,则表示需要手动将其置为无信号,若为FALSE,则会自动变为无信号,千万别和信号量变为有信号状态的方式搞混了!















CreateEvent   的参数有些古怪, 关键理解 第二个TRUE 和 FALSE 的区别



初始值的使用方法!










// 20171227_08.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include "resource.h"

HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
HWND hEdit4;

HANDLE hThread1;

HANDLE hEvent;

DWORD WINAPI ThreadProc2(
LPVOID lpParameter // thread data
)
{
TCHAR szBuffer[10] = {0};
WaitForSingleObject(hEvent,INFINITE);

//读取内容
GetWindowText(hEdit1,szBuffer,10);
SetWindowText(hEdit2,szBuffer);

//MessageBox(0,0,TEXT("1"),0);

//SetEvent(hEvent);

return 0;
}

DWORD WINAPI ThreadProc3(
LPVOID lpParameter // thread data
)
{
TCHAR szBuffer[10] = {0};
WaitForSingleObject(hEvent,INFINITE);

//读取内容
GetWindowText(hEdit1,szBuffer,10);
SetWindowText(hEdit3,szBuffer);

//MessageBox(0,0,TEXT("2"),0);

//SetEvent(hEvent);
return 0;
}


DWORD WINAPI ThreadProc4(
LPVOID lpParameter // thread data
)
{
TCHAR szBuffer[10] = {0};
WaitForSingleObject(hEvent,INFINITE);

//读取内容
GetWindowText(hEdit1,szBuffer,10);
SetWindowText(hEdit4,szBuffer);

//MessageBox(0,0,TEXT("3"),0);

//SetEvent(hEvent);
return 0;
}



DWORD WINAPI MainThreadProc(
LPVOID lpParameter // thread data
)
{

SetWindowText(hEdit1,"1000");

HANDLE hThread[3];

hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);


hThread[0] = CreateThread(NULL,0,ThreadProc2,NULL,0,NULL);
hThread[1] = CreateThread(NULL,0,ThreadProc3,NULL,0,NULL);
hThread[2] = CreateThread(NULL,0,ThreadProc4,NULL,0,NULL);

SetEvent(hEvent);

WaitForMultipleObjects(3,hThread,TRUE,INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hThread[2]);

return 0;
}


BOOL CALLBACK MainDialogProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
hEdit1 = GetDlgItem(hwndDlg,IDC_EDIT1);
hEdit2 = GetDlgItem(hwndDlg,IDC_EDIT2);
hEdit3 = GetDlgItem(hwndDlg,IDC_EDIT3);
hEdit4 = GetDlgItem(hwndDlg,IDC_EDIT4);

SetWindowText(hEdit1,"0");
SetWindowText(hEdit2,"0");
SetWindowText(hEdit3,"0");
SetWindowText(hEdit4,"0");

break;
}
case WM_CLOSE:
{

EndDialog(hwndDlg,0);
break;
}
case WM_COMMAND:
{

switch(LOWORD(wParam))
{
case IDC_BUTTON_BEGIN:
{
//MessageBox(0,0,0,0);
hThread1 = CreateThread(NULL,0,MainThreadProc,NULL,0,NULL);

break;
}

}
}

}

return FALSE;

}


int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.

DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDialogProc);
return 0;
}




发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容