第一个文本框是奖池,右面三个文本框是三个线程抢到的红包数,程序运行结果如下:
解决资源抢占问题,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);</