WIN32多線程搶紅包練習

第一個文本框是獎池,右面三個文本框是三個線程搶到的紅包數,程序運行結果如下:
在這裏插入圖片描述

在這裏插入圖片描述

解決資源搶佔問題,WIN32提供兩種方式:臨界區和互斥體。

臨界區和互斥體的對比:
1、臨界區只能應用於單個進程間的線程控制,互斥體可以跨進程;
2、互斥體可以設定阻塞等待超時,臨界區不能;
3、線程意外終結時,互斥體可以避免死鎖;
4、互斥體效率比臨界區低。

臨界區實現

// RedPack.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

/************************************************************************/
/* 
搶紅包多線程練習
*/
/************************************************************************/

#include <WINDOWS.H>
#include <STDIO.H>
#include <TCHAR.H>
#include "resource.h"

HWND hEditTotal, hEditA, hEditB, hEditC;
CRITICAL_SECTION csTotal;

DWORD WINAPI ThreadA(LPVOID p)
{
	int nTotal;
	int nValue;
	TCHAR szBuffer[100];
	BOOL bFlag = TRUE;
	while (bFlag)
	{		
		EnterCriticalSection(&csTotal);
		GetWindowText(hEditTotal, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nTotal);
		GetWindowText(hEditA, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nValue);		
		if (nTotal >= 50)
		{
			nTotal -= 50;
			nValue += 50;
		}
		else
		{
			bFlag = FALSE;
		}		
		_stprintf(szBuffer, TEXT("%d"), nTotal);
		SetWindowText(hEditTotal, szBuffer);
		_stprintf(szBuffer, TEXT("%d"), nValue);
		SetWindowText(hEditA, szBuffer);
		LeaveCriticalSection(&csTotal);		
		// 延遲
		Sleep(50);
	}	
	return 0;
}

DWORD WINAPI ThreadB(LPVOID p)
{
	int nTotal;
	int nValue;
	TCHAR szBuffer[100];
	BOOL bFlag = TRUE;
	while (bFlag)
	{		
		EnterCriticalSection(&csTotal);
		GetWindowText(hEditTotal, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nTotal);
		GetWindowText(hEditB, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nValue);		
		if (nTotal >= 50)
		{
			nTotal -= 50;
			nValue += 50;
		}
		else
		{
			bFlag = FALSE;
		}		
		_stprintf(szBuffer, TEXT("%d"), nTotal);
		SetWindowText(hEditTotal, szBuffer);
		_stprintf(szBuffer, TEXT("%d"), nValue);
		SetWindowText(hEditB, szBuffer);
		LeaveCriticalSection(&csTotal);		
		// 延遲
		Sleep(50);
	}	
	return 0;
}

DWORD WINAPI ThreadC(LPVOID p)
{
	int nTotal;
	int nValue;
	TCHAR szBuffer[100];
	BOOL bFlag = TRUE;
	while (bFlag)
	{		
		EnterCriticalSection(&csTotal);
		GetWindowText(hEditTotal, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nTotal);
		GetWindowText(hEditC, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nValue);		
		if (nTotal >= 50)
		{
			nTotal -= 50;
			nValue += 50;
		}
		else
		{
			bFlag = FALSE;
		}		
		_stprintf(szBuffer, TEXT("%d"), nTotal);
		SetWindowText(hEditTotal, szBuffer);
		_stprintf(szBuffer, TEXT("%d"), nValue);
		SetWindowText(hEditC, szBuffer);
		LeaveCriticalSection(&csTotal);		
		// 延遲
		Sleep(50);
	}	
	return 0;
}

// 啓動抽獎線程,設置該線程的目的是阻塞等待其他線程結束,然後清理句柄
DWORD WINAPI ThreadStart(LPVOID p)
{
	HANDLE handles[3];
	SetWindowText(hEditA, TEXT("0"));
	SetWindowText(hEditB, TEXT("0"));
	SetWindowText(hEditC, TEXT("0"));
	handles[0] = CreateThread(0,0,ThreadA,0,0,0);
	handles[1] = CreateThread(0,0,ThreadB,0,0,0);
	handles[2] = CreateThread(0,0,ThreadC,0,0,0);
	WaitForMultipleObjects(3, handles, TRUE, INFINITE);
	CloseHandle(handles[0]);
	CloseHandle(handles[1]);
	CloseHandle(handles[2]);
	return 0;
}

BOOL CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_INITDIALOG:
		{		
			hEditTotal = GetDlgItem(hDlg, IDC_EDIT_TOTAL);
			hEditA = GetDlgItem(hDlg, IDC_EDIT_A);
			hEditB = GetDlgItem(hDlg, IDC_EDIT_B);
			hEditC = GetDlgItem(hDlg, IDC_EDIT_C);
			SetWindowText(hEditTotal, TEXT("0"));
			SetWindowText(hEditA, TEXT("0"));
			SetWindowText(hEditB, TEXT("0"));
			SetWindowText(hEditC, TEXT("0"));
			return TRUE;
		}
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON1:
				{
					CreateThread(0,0,ThreadStart,0,0,0);
					return TRUE;
				}
			}
			return TRUE;
		}
	case WM_CLOSE:
		{
			EndDialog(hDlg, 0);
			return TRUE;
		}
	}
	return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	InitializeCriticalSection(&csTotal);	
 	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, MainDlgProc);

	return 0;
}

互斥體實現

// RedPack.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

/************************************************************************/
/* 
搶紅包多線程練習
*/
/************************************************************************/

#include <WINDOWS.H>
#include <STDIO.H>
#include <TCHAR.H>
#include "resource.h"

HWND hEditTotal, hEditA, hEditB, hEditC;
HANDLE hMutex;

DWORD WINAPI ThreadA(LPVOID p)
{
	int nTotal;
	int nValue;
	TCHAR szBuffer[100];
	BOOL bFlag = TRUE;
	while (bFlag)
	{		
		WaitForSingleObject(hMutex, INFINITE);
		GetWindowText(hEditTotal, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nTotal);
		GetWindowText(hEditA, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nValue);		
		if (nTotal >= 50)
		{
			nTotal -= 50;
			nValue += 50;
		}
		else
		{
			bFlag = FALSE;
		}		
		_stprintf(szBuffer, TEXT("%d"), nTotal);
		SetWindowText(hEditTotal, szBuffer);
		_stprintf(szBuffer, TEXT("%d"), nValue);
		SetWindowText(hEditA, szBuffer);
		ReleaseMutex(hMutex);
		// 延遲
		Sleep(50);
	}	
	return 0;
}

DWORD WINAPI ThreadB(LPVOID p)
{
	int nTotal;
	int nValue;
	TCHAR szBuffer[100];
	BOOL bFlag = TRUE;
	while (bFlag)
	{		
		WaitForSingleObject(hMutex, INFINITE);
		GetWindowText(hEditTotal, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nTotal);
		GetWindowText(hEditB, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nValue);		
		if (nTotal >= 50)
		{
			nTotal -= 50;
			nValue += 50;
		}
		else
		{
			bFlag = FALSE;
		}		
		_stprintf(szBuffer, TEXT("%d"), nTotal);
		SetWindowText(hEditTotal, szBuffer);
		_stprintf(szBuffer, TEXT("%d"), nValue);
		SetWindowText(hEditB, szBuffer);
		ReleaseMutex(hMutex);
		// 延遲
		Sleep(50);
	}	
	return 0;
}

DWORD WINAPI ThreadC(LPVOID p)
{
	int nTotal;
	int nValue;
	TCHAR szBuffer[100];
	BOOL bFlag = TRUE;
	while (bFlag)
	{		
		WaitForSingleObject(hMutex, INFINITE);
		GetWindowText(hEditTotal, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nTotal);
		GetWindowText(hEditC, szBuffer, 100);
		_stscanf(szBuffer, TEXT("%d"), &nValue);		
		if (nTotal >= 50)
		{
			nTotal -= 50;
			nValue += 50;
		}
		else
		{
			bFlag = FALSE;
		}		
		_stprintf(szBuffer, TEXT("%d"), nTotal);
		SetWindowText(hEditTotal, szBuffer);
		_stprintf(szBuffer, TEXT("%d"), nValue);
		SetWindowText(hEditC, szBuffer);
		ReleaseMutex(hMutex);
		// 延遲
		Sleep(50);
	}	
	return 0;
}

// 啓動抽獎線程,設置該線程的目的是阻塞等待其他線程結束,然後清理句柄
DWORD WINAPI ThreadStart(LPVOID p)
{
	HANDLE handles[3];
	hMutex = CreateMutex(0, FALSE, "MyTag");
	SetWindowText(hEditA, TEXT("0"));
	SetWindowText(hEditB, TEXT("0"));
	SetWindowText(hEditC, TEXT("0"));
	handles[0] = CreateThread(0,0,ThreadA,0,0,0);
	handles[1] = CreateThread(0,0,ThreadB,0,0,0);
	handles[2] = CreateThread(0,0,ThreadC,0,0,0);
	WaitForMultipleObjects(3, handles, TRUE, INFINITE);
	CloseHandle(handles[0]);
	CloseHandle(handles[1]);
	CloseHandle(handles[2]);
	CloseHandle(hMutex);
	return 0;
}

BOOL CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_INITDIALOG:
		{		
			hEditTotal = GetDlgItem(hDlg, IDC_EDIT_TOTAL);
			hEditA = GetDlgItem(hDlg, IDC_EDIT_A);
			hEditB = GetDlgItem(hDlg, IDC_EDIT_B);
			hEditC = GetDlgItem(hDlg, IDC_EDIT_C);
			SetWindowText(hEditTotal, TEXT("0"));
			SetWindowText(hEditA, TEXT("0"));
			SetWindowText(hEditB, TEXT("0"));
			SetWindowText(hEditC, TEXT("0"));
			return TRUE;
		}
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON1:
				{
					CreateThread(0,0,ThreadStart,0,0,0);
					return TRUE;
				}
			}
			return TRUE;
		}
	case WM_CLOSE:
		{
			EndDialog(hDlg, 0);
			return TRUE;
		}
	}
	return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{	
 	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, MainDlgProc);

	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章