31win32编程基础——信号量解决复杂线程控制问题。

 现在有个任务,要求,先让最上边的编辑框内容加到100,然后开始执行下边的编辑框才能读取操作,并且要求下边的编辑框一次同时执行2个线程?

使用事件能解决这个问题吗?

明显不能,因为事件无法控制同时执行的线程数量,但是信号量可以。

代码如下:

#include <Windows.h>
#include "resource.h"
#include <stdio.h>
HANDLE hSema;
HWND hDialog;
int EditMem[3];
 
DWORD WINAPI ThreadEditProc(
  __in  LPVOID lpParameter
){
    TCHAR sz[20];
    int tmepRed=0;
    WaitForSingleObject(hSema,-1);//相当于减去信号量
    for(int i=0;i<100;i++)
    {
        swprintf(sz,TEXT("%d"),tmepRed);
        SetDlgItemText(hDialog,EditMem[int(lpParameter)],sz);
        tmepRed++;
        Sleep(50);
    }
    swprintf(sz,TEXT("%d"),tmepRed);
    SetDlgItemText(hDialog,EditMem[int(lpParameter)],sz);
    ReleaseSemaphore(hSema,1,NULL);//增加信号
    return 0;
};
 
 
DWORD WINAPI ThreadMainProc(
  __in  LPVOID lpParameter
){
 
    hSema = CreateSemaphore(NULL,0,3,NULL);//初始状态不发信号
    TCHAR sz[20];
    int tempRed;
    HANDLE hThread[3];
    hThread[0] = CreateThread(NULL,NULL,ThreadEditProc,(LPVOID)0,0,NULL);
    hThread[1] = CreateThread(NULL,NULL,ThreadEditProc,(LPVOID)1,0,NULL);
    hThread[2] = CreateThread(NULL,NULL,ThreadEditProc,(LPVOID)2,0,NULL);
    
    for(int i=0;i<100;i++)
    {
        GetDlgItemText(hDialog,IDC_EDIT_ALL,sz,20);
        swscanf(sz,TEXT("%d"),&tempRed);
        tempRed++;
        swprintf(sz,TEXT("%d"),tempRed);
        SetDlgItemText(hDialog,IDC_EDIT_ALL,sz);
        Sleep(50);
    }

    //ReleaseSemaphore(hSema,1,NULL);//控制信号数量,每次发生1个信号,同时可以控制1个线程执行,发送信号
    ReleaseSemaphore(hSema,2,NULL);//控制信号数量,每次发2个信号,同时可以控制2个线程执行。

    WaitForMultipleObjects(3,hThread,TRUE,-1);
    CloseHandle(hThread[0]);
    CloseHandle(hThread[1]);
    CloseHandle(hThread[2]);
    CloseHandle(hSema);
 
    return 0;
};
 
 
BOOL  CALLBACK DialogProc(  HWND hwndDlg,   UINT uMsg,   WPARAM wParam,
  LPARAM lParam){
     
    switch(uMsg)
    {
        case WM_COMMAND:
        {
            WORD Id=LOWORD(wParam);
            WORD EventId = HIWORD(wParam);
            switch(Id)
            {
                case IDC_BUTTON_BEGIN:
                    {
                        HANDLE HMain = CreateThread(NULL,NULL,ThreadMainProc,(LPVOID)hwndDlg,0,NULL);
                    }
                default:
                    {
                        return FALSE;
                    }
  
            }
            return 0;
        }
        case WM_CLOSE:
            {
                EndDialog(hwndDlg,0);
                return 0;
            }
        case WM_INITDIALOG:
            {
                hDialog  = hwndDlg;
                EditMem[0] = IDC_EDIT_H1;
                EditMem[1] = IDC_EDIT_H2;
                EditMem[2] = IDC_EDIT_H3;
                SetDlgItemText(hwndDlg,IDC_EDIT_ALL,TEXT("0"));
                SetDlgItemText(hwndDlg,IDC_EDIT_H1,TEXT("0"));
                SetDlgItemText(hwndDlg,IDC_EDIT_H2,TEXT("0"));
                SetDlgItemText(hwndDlg,IDC_EDIT_H3,TEXT("0"));
 
 
 
                return 0;
            }
    }
  
    return FALSE;
};
 
 
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR    lpCmdLine,
                     int       nCmdShow)
{
     
    DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,DialogProc);
  
    return 0;
}

 

posted @ 2023-11-13 18:08  一日学一日功  阅读(59)  评论(0)    收藏  举报