在MFC里面实现线程的实例
线程是一种从软件到硬件的技术,主要目的是为了提高运行速度,和多任务。
××××××××××××××××××××××××××××××××××××需要储备的资料(他人的)××××××××××××××××××××××××××××
××http://haobinnan.blog.51cto.com/775253/658446
多线程概述
进程和线程都是操作系统的概念。进程是在基于内存的概念,线程是基于CPU的概念。CPU不清楚什么玩意叫进程,CPU处理的任务叫线程。一个进程可以划分成多个线程给CPU处理。一个程序可以有多个进程 用于处理不同的事情。
进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。
线程是进程内部的一个执行单元,系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。
每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,所以线程间的通讯非常方便,多线程技术的应用也较为广泛。
MFC中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。
在MFC中,一般用全局函数AfxBeginThread()来创建并初始化一个线程的运行,该函数有两种重载形式,(为啥叫重载形式呢?因为系统中已经有了这两个函数,在使用的使用给予不同的变量不就是重载的定义吗??是的)分别用于创建工作者线程和用户界面线程。两种重载函数原型和参数分别说明如下:
CreateThread是一个API,而AfxBeginThread是MFC中的一个函数。后者在内部调用了前者。
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
对于工作线程来说,启动一个线程,首先需要编写一个希望与应用程序的其余部分并行运行的函数如Fun1(),
接着定义一个指向CwinThread对象的指针变量*pThread,(在MFC中可以用App)
调用AfxBeginThread(Fun1,param,priority)函数,返回值付给pThread变量的同时一并启动该线程来执行上面的Fun1()函数,
其中Fun1是线程要运行的函数的名字,也既是上面所说的控制函数的名字,param是准备传送给线程函数 Fun1的任意32位值,
priority则是定义该线程的优先级别,它是预定义的常数。
线程函数是回调函数,线程函数在类内必须是静态成员函数,或者是类外声明的全局函数。
因为静态成员函数不能访问类的非静态成员函数,所以在线程函数中要定义一个类的指针指向this指针,就可以用类的指针来调用类的成员函数。
数据传递使用this处理。
无HMI WORK线程
CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc,//指向工作者线程的执行函数的指针,线程函数原型必须声明如下: UINTExecutingFunction(LPVOID pParam);
LPVOID pParam,/**///传递给线程函数的一个32位参数,执行函数将用某种方式解释该值。它可以是数值,或是指向一个结构的指针,甚至可以被忽略;
nPriority=THREAD_PRIORITY_NORMAL,//线程的优先级。如果为0,则线程与其父线程具有相同的优先级;
UINTnStackSize=0,//线程为自己分配堆栈的大小,其单位为字节。如果nStackSize被设为0,则线程的堆栈被设置成与父线程堆栈相同大小;
DWORDdwCreateFlags=0,//如果为0,则线程在创建后立刻开始执行。如果为CREATE_SUSPEND,则线程在创建后立刻被挂起;
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL//线程的安全属性指针,一般为NULL;
);
一个工作线程创建的实例:
环境是VS2010 MFC Win7 64位系统。
<span style="background-color: rgb(0, 204, 204);">public:
//工作线程创建第一步:在某个头文件里面声明一个函数。
static UINT Scada_Operational(LPVOID pParam);
int aaa;
}; extern CTestApp theApp;
</span>
×××
<span style="background-color: rgb(0, 204, 204);">//工作线程创建第二步:在对应的实现文件里面,定义这个函数。
UINT CTestApp::Scada_Operational(LPVOID pParam)
{
Sleep(1000);
AfxMessageBox(_T("准备赋值"));
CTestApp* theApp = (CTestApp*)pParam;
int bb=0; bb= theApp->aaa;
Sleep(1000);
AfxMessageBox(_T("完成赋值")); return 0;
}</span>
×××
<span style="background-color: rgb(0, 204, 204);">//工作线程创建第三步:使用MFC特有的函数AfxBeginThread 将函数变为线程。
AfxBeginThread(Scada_Operational,this);</span>
源代码:http://pan.baidu.com/s/1mgrAxVM
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
UI线程
创建一个用户界面线程,首先要从类CwinThread产生一个派生类,同时必须使用DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE来声明和实现这个CwinThread派生类。
第二步是根据需要重载该派生类的一些成员函数如:ExitInstance();InitInstance();OnIdle(); PreTranslateMessage()等函数,最后启动该用户界面线程,调用AfxBeginThread()函数的一个版 本:
CWinThread*AfxBeginThread(
CRuntimeClass* pThreadClass,//从CWinThread派生的RUNTIME_CLASS类;
intnPriority=THREAD_PRIORITY_NORMAL,//线程优先级,如果为0,则与创建该线程的线程相同;
UINT nStackSize=0,//线程的堆栈大小,如果为0,则与创建该线程的线程相同;
DWORD dwCreateFlags=0,//一个创建标识,如果是CREATE_SUSPENDED,
则在悬挂状态创建线程,在线程创建后线程挂起,否则线程在创建后开始线程的执行。
LPSECURITY_ATTRIBUTESlpSecurityAttrs=NULL//线程的安全属性,NT下有用。
);
范例 :
1、建立一个基于MFC的对话框应用程序。
2、向程序中添加一个以CWinThread为基类的新类CUIThread,该类用于启动一个用户界面线程。
3、向程序中添加一个对话框资源,并建立相应的对话框类CUIThreadDlg,这个对话框的基类是CDialogEx。
该对话框将被作为用户界面线程的主窗口。
4、在UIThread.h中加入#include "UIThreadDlg.h"和
public:
CUIThreadDlg m_dlg;
并在CUIThread::InitInstance()中加入
BOOL CUIThread::InitInstance()
{
// TODO: 在此执行任意逐线程初始化 //用户线程第六步:添加创建程序
m_pMainWnd = &m_dlg;
m_dlg.DoModal();
;
return TRUE;
}
5、CUIThread::InitInstance()中创建的CUIThreadDlg将与主窗口在独立的线程中运行,可以在CUIThreadDlg中加入各种执行耗时任务的代码而不会影响主窗口的运行。
6、在 原始对话框上面添加一个按钮 并创建点击事件响应函数,
//用户线程第七步:添加线程的头文件#include "UIThread.h"。
在函数中添加线程创建
void CTestGszDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//CWinThread* p = AfxBeginThread(RUNTIME_CLASS(CUIThread));
//用户线程第八步:正式创建线程
AfxBeginThread(RUNTIME_CLASS(CUIThread));
}
7:我们创建的线程在结束的时候 销毁我们新建的对话框
int CUIThread::ExitInstance()
{
m_dlg.DestroyWindow();
return CWinThread::ExitInstance();
}
配套源代码:http://pan.baidu.com/s/1jGzLTye
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
几个常用的配套函数
//获取线程对象
CWinThread* AFXAPIAfxGetThread();
//获取当前消息
MSG* AFXAPIAfxGetCurrentMessage();
//结束线程执行
void AFXAPIAfxEndThread(UINTnExitCode,BOOLbDelete =TRUE);
//初始化线程
void AFXAPIAfxInitThread();
//终止线程执行
void AFXAPIAfxTermThread(HINSTANCEhInstTerm =NULL);
在MFC里面实现线程的实例的更多相关文章
- MFC多线程各种线程用法 .
http://blog.csdn.net/qq61394323/article/details/9328301 一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleTh ...
- MFC 多线程及线程同步
一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...
- java线程池实例
目的 了解线程池的知识后,写个线程池实例,熟悉多线程开发,建议看jdk线程池源码,跟大师比,才知道差距啊O(∩_∩)O 线程池类 package thread.pool2; impor ...
- MFC 创建UI线程
对于windows来说,所有的线程都是一样的,但MFC却把线程区分为两种:用户界面(UI)线程和工作者线程.用户界面线程具有消息循环而工作者线程没有.UI线程可以创建窗口并给这些窗口发送消息,工作者线 ...
- 深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)
1.创建和终止线程 在MFC程序中创建一个线程,宜调用AfxBeginThread函数.该函数因参数不同而具有两种重载版本,分别对应工作者线程和用户接口(UI)线程. 工作者线程 CWinThread ...
- MFC在子线程中创建窗口(PostMessage方法)
1.创建子线程 C++创建线程的方式比较多 1)最简单易用的<thread>头文件,但是这种方法创建的子线程中无法给主线程PostMessage消息(也可能是我操作有误,总之没成功) 2) ...
- Java线程基础实例
概述 Java线程是一个在实战开发中经常使用的基础功能,而在Java中线程相关的类在java.lang和java.util.concurrent里 Thread package thread.base ...
- 简单的C#线程开发实例(隔一秒改变一下Label的Text)
要实现的效果:点击按纽,窗口上的label上出现1~100数字的变化. 第一个实例(把窗口上的label上文字改成0): using System; using System.Windows.Form ...
- Java5中的线程池实例讲解
Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活.本文通过一个网络服务器模型,来实践Java5的多线程 ...
随机推荐
- C++ 友元类,友元函数
//友元函数 友元类 #include<iostream> using namespace std; class PointB { public: friend class PointC; ...
- Stochastic Multiple Choice Learning for Training Diverse Deep Ensembles
作者提出的方法是Algotithm 2.简单来说就是,训练的时候,在几个模型中,选取预测最准确的(也就是loss最低的)模型进行权重更新.
- Differential Geometry之第六章平面曲线的整体性质
第六章.平面曲线的整体性质 1.平面的闭曲线 1.1.切线的旋转指数定理 1.2.等周不等式与圆的几何特性 ,其中 2.平面的凸曲线 支撑函数: 2.1.Minkowski问题 2.2.四顶点定理
- java----代理机制或动态类的生成
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- 【BZOJ】1642: [Usaco2007 Nov]Milking Time 挤奶时间(dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1642 果然没能仔细思考是不行的.. 以后要静下心来好好想,不要认为不可做..... 看了题解... ...
- 解决myeclipse启动慢的问题
去掉拼写检查:windows->preferences->General->Editors->Text Editors->Spelling 将"Enable s ...
- OEM无法启动:oracle/product/10.2.0/dbhome_1/oc4j/j2ee/OC4J_DBConsole_localhost.localdomain_orcl not found.
配置OEM环境变量 ORACLE_UNQNAME=$ORACLE_SID 要想打开OEM的web管理程序,必须先启动Database listener,再启动Datebase Control端口监控程 ...
- git与sourceTree
Window:http://my.oschina.net/lunqi/blog/500881?fromerr=bzaPk1Lx MAC:http://www.ithao123.cn/content-8 ...
- jenkins配置邮件报警
author:headsen chen date: 2018-05-15 13:49:21 在jerkins的主配置页面上: 注意:不用 安装什么报警邮件的插件.直接配置就可以了. 系统管理 --- ...
- SpringMVC的解释与搭建Maven私有代理服务器
SpringMVC静态资源处理 通常会配置SpringMVC拦截所有请求 即将DisptcherServlet的url-pattern设置为 / 此时会导致SpringMVC同时拦截.css .j ...