//使用多字符集
#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;
}