复杂线程测试

0x1 项目介绍

字母区写上一段字母 大小在50个以内, 可以自己定义,缓冲区每次只能有一个字母, 4个编辑框可以分别吃字母,最后4个吃货的所有字母加起来等于输入的字母和


0x2 难点

多种线程控制的结合使用, 缓冲区的控制, 吃货区的控制


0x3 项目展示

360截图20180103184048912.jpg


0x4 项目代码


// 20180102_01.cpp : Defines the entry point for the application.
//

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

HANDLE hMainThread;

HWND hEditBuffer1;
HWND hEditBuffer2;
HWND hEditResource;

HWND hEditEatA;
HWND hEditEatB;
HWND hEditEatC;
HWND hEditEatD;

TCHAR ResString[50]={0};
int ResLength=0;

HANDLE hResEvent_Buffer;
HANDLE hResEvent_Eat;
CRITICAL_SECTION cs_res;
CRITICAL_SECTION cs_buffer;

int GetResChar=0;
int GetBufferChar=0;

int nBufferIndex = -1;


DWORD WINAPI EatThread(
						  LPVOID lpParameter   // thread data
)
{
	TCHAR BufferStr[50]={0};
	TCHAR EatStr[50]={0};
	HWND hEditEat[4] = {hEditEatA,hEditEatB,hEditEatC,hEditEatD};
	int nIndex = (int)lpParameter;

	while(GetBufferChar<=ResLength)
	{
		//EnterCriticalSection(&cs_buffer);
		WaitForSingleObject(hResEvent_Eat,INFINITE);
		EnterCriticalSection(&cs_buffer);
		//拿到字符串
		if(nBufferIndex==0)
		{
			//从buffer1中拿
			memset(BufferStr,0,50);
			memset(EatStr,0,50);

			GetWindowText(hEditBuffer1,BufferStr,50);
			
			if(strlen(BufferStr)==0)
			{
				LeaveCriticalSection(&cs_buffer);
				SetEvent(hResEvent_Buffer);
				continue;
			}

			GetWindowText(hEditEat[nIndex],EatStr,50);

			int nEatLength = strlen(EatStr);
			EatStr[nEatLength] = BufferStr[0];
			//设置编辑框
			SetWindowText(hEditEat[nIndex],EatStr);
			SetWindowText(hEditBuffer1,"");

		}else
		{
			//从buffer2中拿
			memset(BufferStr,0,50);
			memset(EatStr,0,50);
			
			GetWindowText(hEditBuffer2,BufferStr,50);
			
			if(strlen(BufferStr)==0)
			{
				LeaveCriticalSection(&cs_buffer);
				SetEvent(hResEvent_Buffer);
				continue;
			}
			
			GetWindowText(hEditEat[nIndex],EatStr,50);
			
			int nEatLength = strlen(EatStr);
			EatStr[nEatLength] = BufferStr[0];
			//设置编辑框
			SetWindowText(hEditEat[nIndex],EatStr);
			SetWindowText(hEditBuffer2,"");
		}
		GetBufferChar++;
		LeaveCriticalSection(&cs_buffer);
		SetEvent(hResEvent_Buffer);
		//LeaveCriticalSection(&cs_buffer);
	}
	return 0;
}



DWORD WINAPI BufferThread(
							LPVOID lpParameter   // thread data
)
{
	TCHAR BufferStr[50]={0};
	HWND hEditBuffer[2] = {hEditBuffer1,hEditBuffer2};
	int nIndex = (int)lpParameter;
	

	while(GetResChar<=ResLength)
	{
		WaitForSingleObject(hResEvent_Buffer,INFINITE);
		EnterCriticalSection(&cs_res);
		
		if(nIndex==0)
		{
			nBufferIndex=0;
		}else{
			nBufferIndex=1;
		}

		memset(BufferStr,0,50);
		GetWindowText(hEditBuffer[nIndex],BufferStr,50);
		
		//如果=1,不要继续拿了
		if(strlen(BufferStr) == 1)
		{
			LeaveCriticalSection(&cs_res);
			SetEvent(hResEvent_Eat);
			continue;
		}


		if(GetResChar==0)
		{
			//sprintf(BufferStr,"%c",ResString[GetResChar]);
			BufferStr[0] = ResString[GetResChar]; 
			SetWindowText(hEditBuffer[nIndex],BufferStr);
			GetResChar++;
			LeaveCriticalSection(&cs_res);
			SetEvent(hResEvent_Eat);
			continue;
		}
		int nLength = strlen(BufferStr);
		BufferStr[nLength] = ResString[GetResChar];
		SetWindowText(hEditBuffer[nIndex],BufferStr);
		GetResChar++;
		

		Sleep(500);
		LeaveCriticalSection(&cs_res);
		SetEvent(hResEvent_Eat);
	}
	return 0;
}




DWORD WINAPI MainThreadProc(
						LPVOID lpParameter   // thread data
)
{
	//分别进入两个缓冲区
	memset(ResString,0,50);
	GetWindowText(hEditResource,ResString,50);
	//sprintf(MyBuffer,"%c",strBuffer[1]);
	//MessageBox(NULL,MyBuffer,0,0);

	//字符串长度
	while(ResString[ResLength]!='\0')
	{
		ResLength++;
	}
	//实际长度 ResLength+1

	HANDLE hBufferThread[2];
	hBufferThread[0] = CreateThread(NULL,0,BufferThread,(void*)0,0,NULL);
	hBufferThread[1] = CreateThread(NULL,0,BufferThread,(void*)1,0,NULL);

	HANDLE hEatThread[4];
	hEatThread[0] = CreateThread(NULL,0,EatThread,(void*)0,0,NULL);
	hEatThread[1] = CreateThread(NULL,0,EatThread,(void*)1,0,NULL);
	hEatThread[2] = CreateThread(NULL,0,EatThread,(void*)2,0,NULL);
	hEatThread[3] = CreateThread(NULL,0,EatThread,(void*)3,0,NULL);

	hResEvent_Buffer = CreateEvent(NULL,FALSE,TRUE,NULL);
	hResEvent_Eat = CreateEvent(NULL,FALSE,FALSE,NULL);

	WaitForMultipleObjects(2,hBufferThread,TRUE,INFINITE);
	WaitForMultipleObjects(4,hEatThread,TRUE,INFINITE);	

	CloseHandle(hBufferThread[0]);
	CloseHandle(hBufferThread[1]);
	CloseHandle(hEatThread[0]);
	CloseHandle(hEatThread[1]);
	CloseHandle(hEatThread[2]);
	CloseHandle(hEatThread[3]);
	
	//关闭事件
	CloseHandle(hResEvent_Buffer);
	CloseHandle(hResEvent_Eat);

	return 0;
}


BOOL CALLBACK MainDialogProc(
							HWND hwndDlg,  // handle to dialog box
							UINT uMsg,     // message
							WPARAM wParam, // first message parameter
							LPARAM lParam  // second message parameter
)
{
	switch(uMsg)
	{
	case WM_INITDIALOG:
		{
			InitializeCriticalSection(&cs_res);
			InitializeCriticalSection(&cs_buffer);

			hEditResource = GetDlgItem(hwndDlg,IDC_EDIT_RESOURCE);
			hEditEatA = GetDlgItem(hwndDlg,IDC_EDIT_EATA);
			hEditEatB = GetDlgItem(hwndDlg,IDC_EDIT_EATB);
			hEditEatC = GetDlgItem(hwndDlg,IDC_EDIT_EATC);
			hEditEatD = GetDlgItem(hwndDlg,IDC_EDIT_EATD);

			hEditBuffer1 = GetDlgItem(hwndDlg,IDC_EDIT_BUFFER1);
			//SetWindowText(hEditBuffer1,"0");
			hEditBuffer2 = GetDlgItem(hwndDlg,IDC_EDIT_BUFFER2);
			//SetWindowText(hEditBuffer2,"0");

			SetWindowText(hEditResource,"0");

			break;
		}
	case WM_CLOSE:
		{
			DeleteCriticalSection(&cs_res);
			DeleteCriticalSection(&cs_buffer);
			EndDialog(hwndDlg,0);
			break;
		}
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON_BEGIN:
				{
					//MessageBox(0,0,0,0);
					//开启主线程
					hMainThread = CreateThread(NULL,0,MainThreadProc,NULL,0,NULL);
					break;
				}
			}
		}
	}
	return FALSE;
}


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.
	
	DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDialogProc);

	return 0;
}




0x5 总结

写完这个小项目, 自己的印象里面的概念其实还是挺晕乎的, 在写代码控制的时候, 也是不断的尝试, 不断的对线程的条件进行限制。。

最后感觉写挺烂的, 参考下吧


进程就是4GB, 线程就是EIP, 多线程速度快, 不过还是单线程好控制!!





原文链接: 复杂线程测试 版权所有,转载时请注明出处,违者必究。
注明出处格式:流沙团 ( https://gyarmy.com/post-357.html )

发表评论

0则评论给“复杂线程测试”