关于windows的进程处理(七)

采用事件的方式来通知从线程运行函数退出来,它的实现原理是这样,在那个死循环里不断地使用 WaitForSingleObject函数来检查事件是否知足,若是知足就退出线程,不知足就继续运行。当在线程里运行阻塞的函数时,就须要在退出线程 时,先要把阻塞状态变成非阻塞状态,好比使用一个线程去接收网络数据,同时使用阻塞的SOCKET时,那么要先关闭SOCKET,再发送事件信号,才能够退出线程的。网络

HANDLE WINAPI CreateEvent(
  _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
  _In_     BOOL                  bManualReset,
  _In_     BOOL                  bInitialState,
  _In_opt_ LPCTSTR               lpName
);
BOOL WINAPI ResetEvent(
  _In_ HANDLE hEvent
);
BOOL WINAPI SetEvent(
  _In_ HANDLE hEvent
);
BOOL WINAPI CloseHandle(
  _In_ HANDLE hObject
);

CreateEvent的参数:函数

  • lpEventAttributes:一个指向SECURITY_ATTRIBUTES结构的指针,肯定返回的句柄是否可被子进程继承。若是lpEventAttributes是NULL,此句柄不能被继承。
  • bManualReset:指定将事件对象建立成手动复原仍是自动复原。若是是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。若是设置为FALSE,当事件被一个等待线程释放之后,系统将会自动将事件状态复原为无信号状态。
  • bInitialState:指定事件对象的初始状态。若是为TRUE,初始状态为有信号状态;不然为无信号状态。
  • lpName:指定事件的对象的名称,是一个以0结束的字符串指针。名称的字符格式限定在MAX_PATH以内。名字是对大小写敏感的。
#include "stdafx.h"
#include <Windows.h>
#include <process.h>

int num = 0;
CRITICAL_SECTION cs;
HANDLE hEvent = NULL;

unsigned WINAPI ThreadInc(void *arg)
{
	int cnt = *(int*)arg;
	WaitForSingleObject(hEvent, INFINITE);
	for (int i = 0; i < cnt; i++)
	{
		num += 1;
		printf("Inc ");
		Sleep(10);
	}
	return 0;
}
unsigned WINAPI ThreadDec(void *arg)
{
	int cnt = *(int*)arg;
	WaitForSingleObject(hEvent, INFINITE);
	for (int i = 0; i < cnt; i++)
	{
		num -= 1;
		printf("Dec ");
		Sleep(10);
	}
	return 0;
}
int main()
{
	int param = 50;
	HANDLE h[2];
	hEvent = CreateEvent(NULL, true, false, NULL);
	h[0]= (HANDLE)_beginthreadex(NULL, 0, ThreadInc, &param, 0, NULL);
	if (h[0] == 0)
	{
		printf("Can not create a thread 1.\n");
		return 0;
	}
	h[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadDec, &param, 0, NULL);
	if (h[1] == 0)
	{
		printf("Can not create a thread 2.\n");
		return 0;
	}
	printf("Ready to run.\n", num);
	SetEvent(hEvent);
	WaitForMultipleObjects(2, h, true, INFINITE);
	ResetEvent(hEvent);
	CloseHandle(hEvent);

	printf("The num is %d, and end of main.\n", num);
	return 0;
}

上述例子中,主程序中CreateEvent建立了一个事件控制,只有在执行SetEvent后事件阻塞才宣告解除,解除后两个进程就分别开始执行。其执行结果为:线程

Ready to run.
Inc Dec Inc Dec Inc Dec Inc Dec Dec Inc Dec Inc Inc Dec Inc Dec Dec Inc Inc Dec
Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec
Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec
Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec
Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec Inc Dec
The num is 0, and end of main.

从上面能够看到其执行是在SetEvent后,其执行是独立运行的。指针

相关文章
相关标签/搜索