【MFC多线程】工作者模式的建立和传递参数,线程内读取主线程变量

之前写的MFC程序是单线程的,在进行循环计算时主界面假死,所以对此进行了修改。作为初学者,寻找资料的时候,发现了两种传递参数的办法,其实归根结底是一种,只不过是传递的类有区别。

参考博客:MFC子线程中更新控件内容的两种办法

在MFC中,一般用全局函数AfxBeginThread()来创建并初始化一个线程(工作者线程,还有一个重载形式是用于创建用户界面线程)的运行。函数的原型是:

CWinThread* AfxBeginThread(
   AFX_THREADPROC pfnThreadProc,
   LPVOID pParam,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 
);

返回值: 成功时返回一个指向新线程的线程对象的指针,否则NULL。

pfnThreadProc:线程的入口函数,声明一定要如下: UINT MyThreadFunction(LPVOID pParam),不能设置为NULL。如果是类成员函数,一定要是静态成员函数。

pParam:传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体或者类对象到线程。一般传递this指针,以方便调用类的非静态成员,因为线程函数是静态函数。

nPriority:线程的优先级,一般设置为0,让它和主线程具有共同的优先级。

nStackSize:指定新创建的线程的栈的大小。如果为 0,新创建的线程具有和主线程一样的大小的栈。

dwCreateFlags:指定创建线程以后,线程有怎么样的标志。可以指定两个值:CREATE_SUSPENDED:线程创建以后,会处于挂起状态,直到调用:ResumeThread。0 : 创建线程后就开始运行。

lpSecurityAttrs:指向一个 SECURITY_ATTRIBUTES 的结构体,用它来标志新创建线程的安全性。如果为 NULL,那么新创建的线程就具有和主线程一样的安全性。

常见用法,这里我从其他地方看到不同的方式。总结:

(1)传递线程参数首先可以自建一个类,然后建立参数指针进行传递,这种用法比较简单。在教学视频搜索文件夹内的程序中,有输入文件路径,关键字两个变量。将两个变量写到自建的类里面,例如建立:

头文件中添加:为了简单放到了公共变量中,为安全性还是放到私有变量中。

class CFind
{
public:
	CString m_strFile=nullptr;
	CString m_strfind = nullptr;
};

cpp中:

void CuoxingTest1Dlg::OnBnClickedButton3()
{
		//建立pitm类
		CFind *pitm = new CFind;
		//传递参数到分线程的类里面
		//1,传递list名
        GetDlgItemText(IDC_EDIT1,pitm->m_strFile)
		//2,传递list数量
	    GetDlgItemText(IDC_EDIT1,pitm->m_strFind)
		//建立多线程
		HANDLE hMultiThread=AfxBeginThread(ThreadProc, pitm);
	}
	
}

UINT  _cdecl  ThreadProc(LPVOID lpParameter)
{
	//改变传递参数的类型
	CFind *pitem = (CFind*)lpParameter;
   //建立输出文档
	
自己的处理代码

	//返回值
	return 0;
	
}

(2)另外一个是传输this指针,我的理解是建立全局指针,指向主进程类,这个就很好玩了。

AfxBeginThread(MyThreadFunction, this); 


传递线程参数为this,即类本身,是为了能在线程函数中获得类中非静态成员变量,因为线程函数是静态函数。

void CuoxingTest1Dlg::OnBnClickedButton3()
{
	nc = m_List.GetItemCount();

	m_progress.SetRange32(0, nc - 1);
	m_progress.SetPos(0);
	m_progress.SetStep(1);

	//建立多线程
	HANDLE hMultiThread = AfxBeginThread(ThreadProc, this);
}
//创建计算分线程
UINT  _cdecl  CuoxingTest1Dlg::ThreadProc(LPVOID lpParameter)
{
	CHuoxingTest1Dlg *pDlg = (CHuoxingTest1Dlg*)lpParameter;

    //控制界面进程的
    pDlg->m_progress.SetPos(pDlg->nc- 1);
	return 0;
}

这里我在线程内就处理完成了,按道理线程内处理结束给主线程发送信息,主线程接到信息作出操作,如果做了就补上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值