1. 程式人生 > >Win32_3-事件&訊號量

Win32_3-事件&訊號量

事件

HANDLE CreateEvent(
		LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全屬性 NULL時為系統預設				
		BOOL bManualReset,                       // TRUE 通過呼叫ResetEvent將事件物件標記為未通知				
		BOOL bInitialState,                      // TRUE 已通知狀態  FALSE未通知狀態				
		LPCTSTR lpName                           // 物件名稱 以NULL結尾的字串				
	);

控制事件

BOOL SetEvent(HANDLE hEvent);

例項程式碼

HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
HWND hEdit4;
HANDLE hThread1;
HANDLE hThread2;
HANDLE hThread3;
HANDLE hThread4;

DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
	//建立事件			
	//預設安全屬性  手動設定未通知狀態(TRUE)  初始狀態未通知 沒有名字 			
	g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	HANDLE hThread[3];
	//建立3個執行緒			
	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);

	//設定文字框的值			
	SetWindowText(hEdit1, "1000");

	//設定事件為已通知			
	SetEvent(g_hEvent);

	//等待執行緒結束 銷燬核心物件			
	WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);
	CloseHandle(hThread[2]);
	CloseHandle(g_hEvent);

	return 0;
}

DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
	TCHAR szBuffer[10] = { 0 };

	//當事件變成已通知時 			
	WaitForSingleObject(g_hEvent, INFINITE);

	//讀取內容			
	GetWindowText(hEdit1, szBuffer, 10);

	SetWindowText(hEdit2, szBuffer);

	return 0;
}
DWORD WINAPI ThreadProc3(LPVOID lpParameter)
{
	TCHAR szBuffer[10] = { 0 };

	//當事件變成已通知時 			
	WaitForSingleObject(g_hEvent, INFINITE);

	//讀取內容			
	GetWindowText(hEdit1, szBuffer, 10);

	SetWindowText(hEdit3, szBuffer);

	return 0;
}
DWORD WINAPI ThreadProc4(LPVOID lpParameter)
{
	TCHAR szBuffer[10] = { 0 };

	//當事件變成已通知時 			
	WaitForSingleObject(g_hEvent, INFINITE);

	//讀取內容			
	GetWindowText(hEdit1, szBuffer, 10);

	SetWindowText(hEdit4, szBuffer);

	return 0;
}

事件達到執行緒同步

執行緒同步

//事件和臨界區								
HANDLE g_hSet, g_hClear;
int g_Max = 10;
int g_Number = 0;

//生產者執行緒函式  								
DWORD WINAPI ThreadProduct(LPVOID pM)
{
	for (int i = 0; i < g_Max; i++)
	{
		WaitForSingleObject(g_hSet, INFINITE);
		g_Number = 1;
		DWORD id = GetCurrentThreadId();
		printf("生產者%d將資料%d放入緩衝區\n", id, g_Number);
		SetEvent(g_hClear);
	}
	return 0;
}
//消費者執行緒函式								
DWORD WINAPI ThreadConsumer(LPVOID pM)
{
	for (int i = 0; i < g_Max; i++)
	{
		WaitForSingleObject(g_hClear, INFINITE);
		g_Number = 0;
		DWORD id = GetCurrentThreadId();
		printf("----消費者%d將資料%d放入緩衝區\n", id, g_Number);
		SetEvent(g_hSet);
	}
	return 0;
}

int main(int argc, char* argv[])
{

	HANDLE hThread[2];

	g_hSet = CreateEvent(NULL, FALSE, TRUE, NULL);
	g_hClear = CreateEvent(NULL, FALSE, FALSE, NULL);

	hThread[0] = ::CreateThread(NULL, 0, ThreadProduct, NULL, 0, NULL);
	hThread[1] = ::CreateThread(NULL, 0, ThreadConsumer, NULL, 0, NULL);

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

	//銷燬 							
	CloseHandle(g_hSet);
	CloseHandle(g_hClear);

	return 0;
}

訊號量

HANDLE CreateSemaphore(

	LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,    //安全控制,一般直接傳入NULL。

	LONG lInitialCount,                             //初始資源數量。0時不傳送訊號 

	LONG lMaximumCount,                             //最大併發數量。lInitialCount<=lMaximumCount

	LPCTSTR lpName                                  //訊號量的名稱,傳入NULL表示匿名訊號量

);
#include "stdafx.h"				
#include "resource.h"				
HANDLE hSemaphore;
HANDLE hThread[3];
HWND hEditSet;
HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
	TCHAR szBuffer[10];
	DWORD dwTimmer = 0;
	WaitForSingleObject(hSemaphore, INFINITE);
	while (dwTimmer < 100)
	{
		Sleep(100);
		memset(szBuffer, 0, 10);
		GetWindowText(hEdit1, szBuffer, 10);
		sscanf(szBuffer, "%d", &dwTimmer);
		dwTimmer++;
		memset(szBuffer, 0, 10);
		sprintf(szBuffer, "%d", dwTimmer);
		SetWindowText(hEdit1, szBuffer);
	}
	ReleaseSemaphore(hSemaphore, 1, NULL);
	return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
	TCHAR szBuffer[10];
	DWORD dwTimmer = 0;
	WaitForSingleObject(hSemaphore, INFINITE);
	while (dwTimmer < 100)
	{
		Sleep(100);
		memset(szBuffer, 0, 10);
		GetWindowText(hEdit2, szBuffer, 10);
		sscanf(szBuffer, "%d", &dwTimmer);
		dwTimmer++;
		memset(szBuffer, 0, 10);
		sprintf(szBuffer, "%d", dwTimmer);
		SetWindowText(hEdit2, szBuffer);
	}
	ReleaseSemaphore(hSemaphore, 1, NULL);
	return 0;
}
DWORD WINAPI ThreadProc3(LPVOID lpParameter)
{
	TCHAR szBuffer[10];
	DWORD dwTimmer = 0;
	WaitForSingleObject(hSemaphore, INFINITE);
	while (dwTimmer < 100)
	{
		Sleep(100);
		memset(szBuffer, 0, 10);
		GetWindowText(hEdit3, szBuffer, 10);
		sscanf(szBuffer, "%d", &dwTimmer);
		dwTimmer++;
		memset(szBuffer, 0, 10);
		sprintf(szBuffer, "%d", dwTimmer);
		SetWindowText(hEdit3, szBuffer);
	}
	ReleaseSemaphore(hSemaphore, 1, NULL);
	return 0;
}
DWORD WINAPI ThreadBegin(LPVOID lpParameter)
{
	TCHAR szBuffer[10];
	DWORD dwMoney = 0;


	hSemaphore = CreateSemaphore(NULL, 0, 3, NULL);

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

	//開始準備紅包			
	while (dwMoney < 1000)
	{
		memset(szBuffer, 0, 10);
		GetWindowText(hEditSet, szBuffer, 10);
		sscanf(szBuffer, "%d", &dwMoney);
		dwMoney++;
		memset(szBuffer, 0, 10);
		sprintf(szBuffer, "%d", dwMoney);
		SetWindowText(hEditSet, szBuffer);
	}
	ReleaseSemaphore(hSemaphore, 2, NULL);

	::WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
	::CloseHandle(hSemaphore);

	return 0;
}
BOOL CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	BOOL bRet = FALSE;

	switch (uMsg)
	{
	case WM_CLOSE:
	{
		EndDialog(hDlg, 0);
		break;
	}
	case WM_INITDIALOG:
	{
		hEditSet = GetDlgItem(hDlg, IDC_EDIT_SET);
		hEdit1 = GetDlgItem(hDlg, IDC_EDIT_1);
		hEdit2 = GetDlgItem(hDlg, IDC_EDIT_2);
		hEdit3 = GetDlgItem(hDlg, IDC_EDIT_3);

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

		break;
	}
	case WM_COMMAND:

		switch (LOWORD(wParam))
		{
		case IDC_BUTTON_BEGIN:
		{
			CreateThread(NULL, 0, ThreadBegin, NULL, 0, NULL);

			return TRUE;
		}
		}
		break;
	}

	return bRet;
}
int APIENTRY WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR     lpCmdLine,
	int       nCmdShow)
{
	// TODO: Place code here.			
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc);
	return 0;
}