- 1、本文档共8页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
深入解读MFC线程创建整理
MFC线程创建之旅——工作线程
1、概述
在应用程序中使用多线程的好处有很多方面,比如可以减少主线程的负担,使应用程序对用户操作的响应更加及时。比如程序中有一个三层的循环操作,如果放在主线程中,一旦开始这个循环,在循环结束之前,应用程序将不会响应用户的任何操作;如果把它放在一个单独的线程中进行,情况就大不一样了。
Win32线程有两种,一是工作线程,就是只有一个线程函数的线程;二是UI线程,就是可以有用户界面的线程。两种线程在本质上一样的,因为windows在创建线程时都是使用的CreateThread函数,在C++中又把它封装成了_beginthread(ex),并为新线程维护了一个消息队列。
在MFC中,我们使用函数AfxBeginThread创建线程,该函数有两个版本,
CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
和
CWinThread* AfxBeginThread(
CRuntimeClass* pThreadClass,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
前者用于创建工作线程,后者用于创建UI线程,我们就从较为简单的工作线程开始我们的MFC线程创建之旅。
2、工作线程
我们先在vc中新建一个win32 console工程,添加代码如下:
UINT WINAPI MyThreadProc( LPVOID pParam )
{
MessageBox(NULL, MyThreadProc, ThreadTour, MB_OK);
return 1;
}
int main(int argc, char* argv[])
{
CWinThread* pThread = AfxBeginThread(( AFX_THREADPROC )MyThreadProc, NULL);
WaitForSingleObject(pThread-m_hThread, INFINITE);
return 1;
}
功能很简单,新建了一个线程,在其中弹出一个对话框。在创建线程处设置断点,开始我们寻古探幽了。
进入ssAfxBeginThread函数(执行到该行时,按F11)后,我们见到如下代码:
图1
在这里,我进入pThread-CreateThread函数,该函数的代码如下:
图2
在CWinThread::CreateThread函数中,首先声明了了_AFX_THREAD_STARTUP类型的变量startup,该类型变量用于保存创建线程(父线程)状态,当前pThread指针及用来进行同步的事件,我们传入的线程函数和线程参数已经通过该变量的pThread参数进入该startup中了;而随后执行了C++的_beginthreadex函数又把startup做为了参数,究竟要把我们的最初传入的函数和参数做何处理,而且还引入一个_AfxThreadEntry参数,看名字好像是线程入口,它是真的入口吗?接下来,我们进入_begingthreadex中探个究竟。
图3
总算找到了创建线程的API函数CreateThread,先看看指定的线程函数_threadstartex吧。
图4
在这里有一个线程局部存储器(Tls),我们大概了解一下,系统为进行中的每个线程维护了一个数组,但同一进程中的所有线程又只能使用同一个索引(就是我们在图中看到的__tlsindex),可以通过TlsSetValue向其中存放一个指针,通过TlsGetValue获取该存放的指针。更详细的资料,请参阅MSDN。
在_threadstartex中运行了_AfxThreadEntry函数,到这里,我们就知道了,AfxThreadEntry并不是真正的线程入口,但们当前传入的线程函数和线程参数哪儿去了呢?我们再看一个AfxThreadEntry。在其中我们找到了当初传入的线程函数和线程参数:
图5
好了,现在我们整理一个,看一看AfxBeginThread的整个流程:
图6
AfxBeginThread把CreateThreae进行了如此这般的封装是为了什么呢?对照图6,我们简单
您可能关注的文档
- 江西考德上公培教你三招防止面试中大脑突然“短路”.doc
- 江西考德上公培江西考德上12月17日20道行测题.doc
- 江西考德上公培行测天天练1月11日行测题(20道).doc
- 污水处理厂工艺流程图.doc
- 污水处理厂设计步骤.doc
- 污水处理基本常用术语、名词介绍.doc
- 汽车窗框有与无的优缺点.docx
- 汽车精益集成产品开发(LiPD) 背景介绍.docx
- 江西考德上公培2014年江西农信社考试金融基础知识真题.doc
- 汽车精益集成产品开发(LiPD)体系介绍.docx
- 2024年中国钽材市场调查研究报告.docx
- 2024年中国不锈钢清洗车市场调查研究报告.docx
- 2024年中国分类垃圾箱市场调查研究报告.docx
- 2024年中国水气电磁阀市场调查研究报告.docx
- 2024年中国绿藻片市场调查研究报告.docx
- 2010-2023历年初中毕业升学考试(青海西宁卷)数学(带解析).docx
- 2010-2023历年福建厦门高一下学期质量检测地理卷.docx
- 2010-2023历年初中数学单元提优测试卷公式法(带解析).docx
- 2010-2023历年初中毕业升学考试(山东德州卷)化学(带解析).docx
- 2010-2023历年初中毕业升学考试(四川省泸州卷)化学(带解析).docx
文档评论(0)