采用事件内核对象(Event)控制子线程的退出

有时候会有需要设置某种标志位后,子线程就退出,这也是很常见的话题,通过全局变量可以做到,这篇文章是通过Event对象实现,没有太多需要特别说明的,都是很常见的例子。直接贴上代码来了,函数的名称都很直观。当在键盘上按下CTRL + C时,便会设置线程退出。


/****************************************
*程序名称:EventFunc,采用事件内核对象(Event)控制子线程的退出。
*创建日期:2013年7月18日
****************************************/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>


BOOL InitEventFunc();
BOOL ExitEventFunc();
void ClearEventFunc();

DWORD WINAPI EventFunc(LPVOID pContext);
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType);

typedef struct _THARG{
	HANDLE	hSignal;
}THAGR;

BOOL	ExitFlag = FALSE;

int _tmain(int argc, LPTSTR argv[])
{
	SetConsoleCtrlHandler(HandlerRoutine, TRUE);
	
	InitEventFunc();

	//wait the thread to set flag TRUE
	while (!ExitFlag){
		Sleep(5000);
		Beep(2000, 300);
	}

	ClearEventFunc();
	_tprintf(_T("main exit!\n"));

	return 0;
}


static HANDLE	hSignal = NULL, hThread = NULL;
BOOL InitEventFunc()
{
	THAGR	*pArg = malloc(sizeof(THAGR));

	if (!pArg){
		_tprintf(_T("malloc failed!\n"));
		return FALSE;
	}

	hSignal = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (NULL == hSignal){
		_tprintf(_T("CreateEvent failed!\n"));
		free(pArg);
		return FALSE;
	}

	pArg->hSignal = hSignal;
	hThread = CreateThread(NULL, 0, EventFunc, pArg, 0, NULL);
	if (NULL == hThread){
		_tprintf(_T("CreateThread failed!\n"));
		free(pArg);
		CloseHandle(hSignal);
		return FALSE;
	}

	return TRUE;
}


BOOL ExitEventFunc()
{
	SetEvent(hSignal);

	return TRUE;
}


void ClearEventFunc()
{
	//调用SetEvent后直接CloseHandle,会使得hSignal被销毁,子线程上的wait操作会以失败告终。
	if (hSignal)
		CloseHandle(hSignal);
	if (hThread)
		CloseHandle(hThread);
}


DWORD WINAPI EventFunc(LPVOID pContext)
{
	THAGR	*pArg = (THAGR*)pContext;
	DWORD	dwRet;

	while ( (dwRet = WaitForSingleObject(pArg->hSignal, 0)) == WAIT_TIMEOUT ){

		_tprintf(_T("In EventFunc, do something!\n"));
		Sleep(1000);
	}// end while

	if (WAIT_OBJECT_0 == dwRet)
		_tprintf(_T("EventFunc: event signaled\n"));
	else if (WAIT_FAILED == dwRet)
		_tprintf(_T("EventFunc: wait event failed, error: %d!\n"), GetLastError());
	_tprintf(_T("EventFunc exit!\n"));

	//to terminate the main function
	ExitFlag = TRUE;

	return 0;
}


//处理CTRL+C键盘事件
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
{
	switch (dwCtrlType)
	{
	case CTRL_C_EVENT:
		ExitEventFunc();
		break;
	default:
		break;
	}
	return TRUE;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值