欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Win32_3-线程控制--事件&信号量

程序员文章站 2022-06-04 21:47:42
...

事件

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;
}
相关标签: 事件 信号量