一、功能说明
目的:当主线程需要处理大量数据导致耗费时间很长时,主线程界面的进度条会卡顿不刷新,无法实时保持进度,因此需要将进度条显示与数据处理分开,将数据处理过程放在新建的线程中,主界面主要用来显示进度情况。而处理数据又可进一步拆分为多个线程且需要线程互斥,此功能演示情况如下:
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);
}
}
三、效果
多线程处理比单线程速度快上很多。
版权声明:本文为m0_37251750原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。