流沙团
复杂线程测试
2018-1-3 流沙团


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, 多线程速度快, 不过还是单线程好控制!!

















发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容