基于MFC的多线程编程实例AfxMessageBegin

来源:互联网 发布:手机淘宝充值中心 编辑:程序博客网 时间:2024/06/01 09:28

 

MFC的多线程函数AfxBeginThread包含了两种版本,一种是工作者线程,一种是用户界面线程。本文主要讲解的是工作者线程的用法和提供一个实例。如果需要用户界面的用法,可以参考这篇文章http://www.cnblogs.com/lidabo/p/3489639.html。

一、工作者线程AfxBeginThread用法

1.1首先比较工作者线程函数和用户界面线程函数的异同

1.1.1工作者线程AfxBeginThread原型:(必看)

CWinThread* AFXAPI  AfxBeginThread(

       AFX_THREADPROC  pfnThreadProc,

       LPVOID  pParam,

       int  nPriority,

       UINT nStackSize,

       DWORD  dwCreateFlags,

       LPSECURITY_ATTRIBUTES  lpSecurityAttrs)

各个参数功能详解如下:

参数1:线程的入口函数,返回值一定为UINT,函数参数为:LPVOID,例如: UINT MyThreadFunction( LPVOID pParam ); 

参数2 :传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体入线程.

参数3:指定线程优先级,如果为0,则与创建该线程的线程相同;

参数4:指定线程的堆栈大小,如果为0,则与创建该线程的线程相同;

参数5:创建标识,如果是CREATE_SUSPENDED,则在悬挂状态创建线程,在线程创建后线程挂起,否则线程在创建后开始线程的执行。

参数6:表示线程的安全属性,NT下有用。

1.1.2用户界面线程AfxBeginThread原型:(可以不看)

CWinThread* AFXAPI AfxBeginThread(

       CRuntimeClass* pThreadClass,

       intnPriority,

       UINTnStackSize,

       DWORDdwCreateFlags,

       LPSECURITY_ATTRIBUTES lpSecurityAttrs)

各个参数功能详解如下:

参数1:是从CWinThread派生的RUNTIME_CLASS类;

参数2:指定线程优先级,如果为0,则与创建该线程的线程相同;

参数3:指定线程的堆栈大小,如果为0,则与创建该线程的线程相同;

参数4:是一个创建标识,如果是CREATE_SUSPENDED,则在悬挂状态创建线程,在线程创建后线程挂起,否则线程在创建后开始线程的执行。

参数5:表示线程的安全属性,NT下有用。

二、工作者线程AfxBeginThread函数用法实例

调用工作者线程AfxBeginThread函数的具体步骤如下所示:

2.1首先创建基于对话框的MFC工程后,在主对话框添加一个按钮控件(命名为打开线程),两个编辑框控件(功能是分别显示主线程状态和子线程状态),如下图所示:

 2.2双击【打开线程】按钮函数,在按钮事件处理函数中,添加如下代码(可直接copy,修改一下两个对应编辑框ID和一个按钮ID就行)

if (ThreadFlag)

       {

              //关闭线程函数

              ThreadFlag = FALSE;//线程标识一定要放在最前面,否则函数执行会出现莫名其妙错误!!!

              GetDlgItem(IDC_BUTTON_TEST)->SetWindowTextA("打开线程");//AfxBeginThread线程的关闭,利用函数执行完毕后,自动返回,然后创建的线程也跟着关闭,对应资源也跟着释放。IDC_BUTTON_TEST按钮ID号,要修改成按钮上的ID号

              return;

       }

       else

       {

              //创建线程函数

              ThreadFlag = TRUE;//线程标识一定要放在最前面,否则函数执行会出现莫名其妙错误!!!

              HANDLE hMultiThread = AfxBeginThread(ChildThread,/*(LPVOID)*/this,THREAD_PRIORITY_IDLE);//ChildThread线程函数入口(返回值为UINT,参数为LPVIOD lParam  this入口点函数参数  THREAD_PRIORITY_IDLE设置优先级 参数45分别指定线程的堆栈大小(0:与参将线程相同)、创建标识(创建后悬挂CREATE_SUSPENDED或者立即执行)、安全属性,含义同用户界面线程

              GetDlgItem(IDC_EDIT_MAIN)->SetWindowTextA("主线程开启");  //IDC_EDIT_MAIN主线程对话框ID号,要修改成自己的主线程对话框ID号

              GetDlgItem(IDC_BUTTON_TEST)->SetWindowTextA("关闭线程");//IDC_BUTTON_TEST子线程对话框ID号,要修改成自己的子线程对话框ID号

              return;

       }

 

2.3在按钮函数的上面,添加如下代码:(可直接copy,修改一下对应编辑框ID就行)

UINT ChildThread(LPVOIDlParam)//多线程入口点函数,相当于另一个main,CPU或同时执行MFC的主线程和ChildThread线程函数

{

       CMFCMultiThreadTest1Dlg* pDlg = (CMFCMultiThreadTest1Dlg*)lParam;//创建一个指向主对话框的句柄

       CStringstr;

       intThreadCound = 1;

       while(pDlg->ThreadFlag)

       {

              str.Format(_T("子线程开启第%d"), ThreadCound++);//

              pDlg->GetDlgItem(IDC_EDIT_CHILD)->SetWindowTextA(str);//设置子对话框显示str的内容,pDlg指向主对话框类入口点。编辑框和按钮控件都在主对话框上,所以可以通过获取主对话框类上的句柄,调用和修改主对话框上按钮控件类和编辑框类。IDC_EDIT_CHILD子线程编辑框的ID,需要修改为自己子对话框ID号

              Sleep(1000);//定时1秒钟

       }

       return0;

}

2.4在主对话框Dlg头文件,加入如下代码:(注意:是创建工程主对话框下的头文件,带有Dlg的.比如我创建的工程命名为CMFCMultiThreadTest1Dlg,则主对话框头文件是CMFCMultiThreadTest1Dlg.h

int ThreadFlag;//线程开启和关闭标志值,是全局变量


2.5在CMFCMultiThreadTest1Dlg::OnInitDialog()下面,添加如下代码:

ThreadFlag = FALSE;

 三、函数编译执行后,得到的结果如下图所示:

程序运行后的图


点击【打开线程】按钮后的图



 点击【关闭按钮】后的图


参考内容:

http://blog.sina.com.cn/s/blog_4f122cbf0100yxza.html

https://jingyan.baidu.com/article/597a064363ba76312b5243a1.html

http://www.cnblogs.com/lidabo/p/3489639.html

http://blog.csdn.net/sd2131512/article/details/6601228

 

 

 

原创粉丝点击