0x1 项目介绍
字母区写上一段字母 大小在50个以内, 可以自己定义,缓冲区每次只能有一个字母, 4个编辑框可以分别吃字母,最后4个吃货的所有字母加起来等于输入的字母和
0x2 难点
多种线程控制的结合使用, 缓冲区的控制, 吃货区的控制
0x3 项目展示
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, 多线程速度快, 不过还是单线程好控制!!
0则评论给“复杂线程测试”