CreateEvent 、 SetEvent 、 ResetEvent 的简单测试

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;
}  


原文链接: CreateEvent 、 SetEvent 、 ResetEvent 的简单测试 版权所有,转载时请注明出处,违者必究。
注明出处格式:流沙团 ( https://gyarmy.com/post-351.html )

发表评论

0则评论给“CreateEvent 、 SetEvent 、 ResetEvent 的简单测试”