關於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後,其執行是獨立運行的。指針

相關文章
相關標籤/搜索