消费者问题及线程同步与互斥练习

//使用多字符集

#include <windows.h>
#include "resource.h"
#include <stdio.h>

HWND hEditRES;
HWND hEditBUF;
HWND hEditBUF2;
HWND hEditA;
HWND hEditB;
HWND hEditC;
HWND hEditD;

//缓冲区文本框句柄数组
HWND hEditBuffer[2];
//消费者文本框句柄数组
HWND hEditCustomer[4];
//线程句柄数组
HANDLE hThread[5];

//信号量:缓冲区有空闲
HANDLE hSemaphoreEmpty;
//信号量:缓冲区有资源
HANDLE hSemaphoreFull;
//互斥体:缓冲区
CRITICAL_SECTION g_Buffer_CS;

//生产者线程
DWORD WINAPI ThreadProduct(LPVOID lpParameter)
{
	TCHAR szBuffer[256];
	TCHAR szTemp[2];//每次取一个字符
	DWORD dwLength;
	//获得资源框信息,判断字符串长度
	memset(szBuffer, 0, 256);
	GetWindowText(hEditRES, szBuffer, 256);
	dwLength = strlen(szBuffer);
	if (dwLength == 0)
		return -1;
	for (DWORD i = 0; i < dwLength; i++)
	{
		//等待缓冲区有空闲可写的信号,hSemaphoreEmpty -1
		WaitForSingleObject(hSemaphoreEmpty ,INFINITE);
		//将字符存储到缓冲区中
			for(DWORD k = 0; k < 2; k++)
			{
				//判断缓冲区文本框字符是否为字符"0",是则缓冲区为空
				EnterCriticalSection(&g_Buffer_CS);
				memset(szTemp, 0, 2);
				GetWindowText(hEditBuffer[k], szTemp,2);
				if (!strcmp(szTemp, "0"))
				{
					//写入缓冲区文本框
					TCHAR szT[2] = { 0 };//第二个字节为0构成字符
					memcpy(szT, &szBuffer[i], 1);
					SetWindowText(hEditBuffer[k], szT);
					LeaveCriticalSection(&g_Buffer_CS);
					break;
				}
				LeaveCriticalSection(&g_Buffer_CS);
			}
			//hSemaphoreFull+1
			Sleep(500);
			ReleaseSemaphore(hSemaphoreFull, 1, NULL);
	}
	

	return 0;
}

//消费者线程
DWORD WINAPI ThreadCustomer(LPVOID lpParameter)
{
	TCHAR szBuffer[256];
	TCHAR szTemp[2];
	TCHAR szNewBuffer[256];
	DWORD dwIndex = (DWORD)lpParameter;
	DWORD dwExitCode;
	//当条件允许可以执行时
	while (true)
	{
		//等待信号,hSemaphoreFull - 1
		dwExitCode = WaitForSingleObject(hSemaphoreFull, 10000);
		if (dwExitCode == 0x102)
			return -1;
		//循环从缓冲区文本框中读取字母
		EnterCriticalSection(&g_Buffer_CS);
		for (DWORD i = 0; i < 2; i++)
		{	
			memset(szTemp, 0, 2);
			GetWindowText(hEditBuffer[i], szTemp,2);
			//判断是否为0,如果不是0,写入自己的文本框中
			if (strcmp(szTemp, "0") != 0)
			{
				//拼接消费者框原有的字母和新拿到的字母
				memset(szBuffer, 0, 256);
				GetWindowText(hEditCustomer[dwIndex], szBuffer, 256);
				sprintf(szNewBuffer, "%s-%s", szBuffer, szTemp);
				//写入自己的文本框
				SetWindowText(hEditCustomer[dwIndex], szNewBuffer);
				Sleep(500);
				//将缓冲区被读取的位置"0"
				SetWindowText(hEditBuffer[i], "0");
				break;
			}	
		}
		LeaveCriticalSection(&g_Buffer_CS);
		//修改缓冲区有资源信号量,缓hSemaphoreEmpty + 1
		Sleep(500);
		ReleaseSemaphore(hSemaphoreEmpty, 1, NULL);
	}
	return 0;
}

DWORD WINAPI ThreadMain(LPVOID lpParameter)
{
	//创建信号量,实现线程同步
	//信号量:缓冲区有空闲,通知生产者线程往缓冲区存放字母
	hSemaphoreEmpty = CreateSemaphore(NULL, 2, 2, NULL);
	//信号量:缓冲区有资源,通知消费者拿字母
	hSemaphoreFull = CreateSemaphore(NULL, 0, 2, NULL);
	//初始化临界区
	InitializeCriticalSection(&g_Buffer_CS);
	
	hThread[0] = ::CreateThread(NULL, 0, ThreadProduct, NULL, 0, NULL);
	hThread[1] = ::CreateThread(NULL, 0, ThreadCustomer, (PVOID)0, 0, NULL);
	hThread[2] = ::CreateThread(NULL, 0, ThreadCustomer, (PVOID)1, 0, NULL);
	hThread[3] = ::CreateThread(NULL, 0, ThreadCustomer, (PVOID)2, 0, NULL);
	hThread[4] = ::CreateThread(NULL, 0, ThreadCustomer, (PVOID)3, 0, NULL);
	//等待线程结束
	::WaitForMultipleObjects(5, hThread, TRUE, INFINITE);
	//关闭句柄
	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);
	CloseHandle(hThread[2]);
	CloseHandle(hThread[3]);
	CloseHandle(hThread[4]);
	CloseHandle(hSemaphoreEmpty);
	CloseHandle(hSemaphoreFull);
	DeleteCriticalSection(&g_Buffer_CS);

	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:
	{
		hEditRES = GetDlgItem(hDlg, IDC_EDIT_RES);
		hEditBUF = GetDlgItem(hDlg, IDC_EDIT_BUF);
		hEditBUF2 = GetDlgItem(hDlg, IDC_EDIT_BUF2);
		hEditBuffer[0] = hEditBUF;
		hEditBuffer[1] = hEditBUF2;
		hEditA = GetDlgItem(hDlg, IDC_EDIT_A);
		hEditB = GetDlgItem(hDlg, IDC_EDIT_B);
		hEditC = GetDlgItem(hDlg, IDC_EDIT_C);
		hEditD = GetDlgItem(hDlg, IDC_EDIT_D);
		hEditCustomer[0] = hEditA;
		hEditCustomer[1] = hEditB;
		hEditCustomer[2] = hEditC;
		hEditCustomer[3] = hEditD;

		SetWindowText(hEditRES, "");
		SetWindowText(hEditBUF, "0");
		SetWindowText(hEditBUF2, "0");
		SetWindowText(hEditA, "");
		SetWindowText(hEditB, "");
		SetWindowText(hEditC, "");
		SetWindowText(hEditD, "");

		break;
	}
	case WM_COMMAND:

		switch (LOWORD(wParam))
		{
		case IDC_BUTTON_START:
		{
			CreateThread(NULL, 0, ThreadMain, NULL, 0, NULL);
			return TRUE;
		}  
		}
		break;
	}

	return bRet;
}


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


	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值