深入解读MFC线程创建.doc

  1. 1、本文档共8页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 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,我们简单

文档评论(0)

chenchena + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档