多线程对比:通过创建线程的方式来同步MFC进度条显示

一、功能说明

目的:当主线程需要处理大量数据导致耗费时间很长时,主线程界面的进度条会卡顿不刷新,无法实时保持进度,因此需要将进度条显示与数据处理分开,将数据处理过程放在新建的线程中,主界面主要用来显示进度情况。而处理数据又可进一步拆分为多个线程且需要线程互斥,此功能演示情况如下:
1) 单线程处理数据:主界面线程 + (数据处理子线程1);共2个线程 <主+子>
2) 多线程处理数据:主界面线程 + (数据处理子线程
4);共5个线程 <主+子*4>
在这里插入图片描述

二、功能实现

// MutiThreadDlg.h : 头文件
//

#pragma once
#include "afxcmn.h"
#include "Myprogressctrl.h"

#include <vector>
using namespace std;

struct threadInfo  
{
    
      
	UINT nStart;  
	UINT nEnd;  
	CProgressCtrl* pctrlProgress; 
};  

DWORD WINAPI SingleThreadFunc(LPVOID lpParam);  
DWORD WINAPI MutiThreadFunc(LPVOID lpParam);  


// CMutiThreadDlg 对话框
class CMutiThreadDlg : public CDialogEx
{
    
    
// 构造
public:
	CMutiThreadDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum {
    
     IDD = IDD_MUTITHREAD_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持

// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedBtnMuti();
	afx_msg void OnBnClickedBtnSingle();
	
	CMyProgressCtrl m_ctrlProgress;
	std::vector<threadInfo> m_vecInfo;
};
// MutiThreadDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "MutiThread.h"
#include "MutiThreadDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

volatile UINT m_nPosition = 0;
HANDLE m_hMutex; // 线程互斥

DWORD WINAPI SingleThreadFunc(LPVOID lpParam) 
{
    
      
	threadInfo* pInfo = (threadInfo*)lpParam;  
	int nStart = pInfo->nStart;
	int nEnd = pInfo->nEnd;

	for(int i = nStart;i <= nEnd; i++)  
	{
    
      
		pInfo->pctrlProgress->SetPos(i);  
		Sleep(300); 
	}  

	return 0;  
}  

DWORD WINAPI MutiThreadFunc(LPVOID lpParam)
{
    
    
	threadInfo* pInfo = (threadInfo*)lpParam;  
	int nStart = pInfo->nStart;
	int nEnd = pInfo->nEnd;

	for(int i = nStart;i <= nEnd; i++)  
	{
    
      
		++m_nPosition;
		Sleep(300);

		WaitForSingleObject(m_hMutex, INFINITE);
		pInfo->pctrlProgress->SetPos(m_nPosition);  
		ReleaseMutex(m_hMutex);
	}  

	return 0;  
}

// CMutiThreadDlg 对话框

CMutiThreadDlg::CMutiThreadDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CMutiThreadDlg::IDD, pParent)
{
    
    
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

&&&&&&&&&&&………………………………


void CMutiThreadDlg::OnBnClickedBtnSingle()
{
    
    
	// TODO: 在此添加控件通知处理程序代码
	m_vecInfo.clear();
	m_ctrlProgress.SetPos(0);

	threadInfo sInfo;
	sInfo.nStart = 1;
	sInfo.nEnd = 100;
	sInfo.pctrlProgress = &m_ctrlProgress;  
	m_vecInfo.push_back(sInfo);
	threadInfo& sInfoTemp = m_vecInfo.at(0);

	DWORD ThreadID;
	HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)SingleThreadFunc,&sInfoTemp,0,&ThreadID);
	CloseHandle(hThread);
}

void CMutiThreadDlg::OnBnClickedBtnMuti()
{
    
    
	// TODO: 在此添加控件通知处理程序代码
	m_vecInfo.clear();
	m_ctrlProgress.SetPos(0);

	threadInfo sInfo1;
	sInfo1.nStart = 1;
	sInfo1.nEnd = 25;
	sInfo1.pctrlProgress = &m_ctrlProgress;  
	m_vecInfo.push_back(sInfo1);

	threadInfo sInfo2;
	sInfo2.nStart = 1;
	sInfo2.nEnd = 25;
	sInfo2.pctrlProgress = &m_ctrlProgress;  
	m_vecInfo.push_back(sInfo2);

	threadInfo sInfo3;
	sInfo3.nStart = 1;
	sInfo3.nEnd = 25;
	sInfo3.pctrlProgress = &m_ctrlProgress;  
	m_vecInfo.push_back(sInfo3);

	threadInfo sInfo4;
	sInfo4.nStart = 1;
	sInfo4.nEnd = 25;
	sInfo4.pctrlProgress = &m_ctrlProgress;  
	m_vecInfo.push_back(sInfo3);

	// 防止多次点击创建多个锁
	if (m_hMutex)
	{
    
    
		CloseHandle(m_hMutex);
		m_hMutex = NULL;
	}

	m_hMutex = CreateMutex(NULL, FALSE, _T("progress"));

	for (int i = 0; i < m_vecInfo.size(); ++i)
	{
    
    
		threadInfo& sInfoTemp = m_vecInfo.at(i);
		DWORD ThreadID;
		HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MutiThreadFunc,&sInfoTemp,0,&ThreadID);
		CloseHandle(hThread);
	}
}

三、效果

多线程处理比单线程速度快上很多。

猜你喜欢

转载自blog.csdn.net/m0_37251750/article/details/120413931
今日推荐