当前位置: 首页 > 编程笔记 >

VC中CWinThread类以及和createthread API的区别分析

桑璞
2023-03-14
本文向大家介绍VC中CWinThread类以及和createthread API的区别分析,包括了VC中CWinThread类以及和createthread API的区别分析的使用技巧和注意事项,需要的朋友参考一下

本文实例讲述了VC中CWinThread类以及和createthread API的区别分析,分享给大家供大家参考。具体分析如下:

CWinThread

CObject
 └CCmdTarget
    └CWinThread

CWinThread对象代表在一个应用程序内运行的线程。运行的主线程通常由CWinApp的派生类提供;CWinApp由CWinThread派生。另外,CWinThread对象允许一给定的应用程序拥有多个线程。

CWinThread支持两种线程类型:工作者线程(Worker Thread)和用户界面线程(UI thread)。工作者线程没有收发消息的功能(没有消息队列):例如,在电子表格应用程序中进行后台计算的线程。

用户界面线程具有收发消息的功能,并处理从系统收到的消息。CWinApp及其派生类是用户界面线程的例子。其它用户界面线程也可由CWinThread直接派生。

CWinThread类的对象存在于线程的生存期。如果你希望改变这个特性,将m_bAutoDelete设为FALSE。

要使你的代码和MFC是完全线程安全的,CWinThread类是完全必要的。框架使用的用来维护与线程相关的信息的线程局部数据由CWinThread对象管理。由于依赖CWinThread来处理线程局部数据(Thread Local Storage),任何使用MFC的线程必须由MFC创建。例如,由运行时函数_beginthreadex创建的线程不能使用任何MFC API。

为了创建一个线程,调用AfxBeginThread函数。根据你需要工作者线程还是用户界面线程,有两种调用AfxBeginThread的格式。如果你需要用户界面线程,则将指向你的CWinThread派生类的CRuntimeClass的指针传递给AfxBeginThread。如果你需要创建工作者线程,则将指向控制函数的指针和控制函数的参数传递给AfxBeginThread。对于工作者线程和用户界面线程,你可以指定可选的参数来修改优先级,堆栈大小,创建标志和安全属性。

AfxBeginThread线程将返回指向新的CWinThread对象的指针。
与调用AfxBeginThread相反,你可以构造一个CWinThread派生类的对象,然后调用CreateThread。如果你需要在连续创建和终止线程的执行之间重复使用CWinThread对象,这种两步构造方法非常有用。

CWinThread类成员

数据成员

m_bAutoDelete                      指定线程结束时是否要销毁对象 
m_hThread                             当前线程的句柄 
m_nThreadID                         当前线程的ID 
m_pMainWnd                         保存指向应用程序的主窗口的指针 
m_pActiveWnd                       指向容器应用程序的主窗口,当一个OLE服务器被现场激活时 

构造函数

CWinThread                           构造一个CWinThread对象 
CreateThread                          开始一个CWinThread对象的执行 

操作

GetMainWnd                          查询指向线程主窗口的指针 
GetThreadPriority                    获取当前线程的优先级 
PostThreadMessage               向另外的CWinThread对象传递一条消息 
ResumeThread                       减少一个线程的挂起计数 
SetThreadPriority                   设置当前线程的优先级 
SuspendThread                     增加一个线程的挂起计数 

可重载函数

ExitInstance                         重载以进行线程终止时的清理工作 
InitInstance                           重载以实现线程实例的初始化 
OnIdle                                   重载以进行线程特定的空闲操作 
PreTranslateMessage           在消息被发送到Windows函数TranslateMessage和DispatchMessage之前过滤消息 
IsIdleMessage                      检测特定的消息 
ProcessWndProcException    截获线程消息和命令处理函数出现的所有未处理的异常 
ProcessMessageFilter           在特定的消息到达应用程序之前截获消息 
Run                                       线程的具有消息收发功能的控制函数,可重载以定制缺省的消息循环 

AfxBeginThread和CreateThread具体区别

具体说来,CreateThread这个 函数是windows提供给用户的 API函数,是SDK的标准形式.
AfxBeginThread,是编译器对原来的CreateThread函数的封装,用与MFC.
而_beginthread是C的运行库函数。               
在使用AfxBeginThread时,线程函数的定义为:UINT  _yourThreadFun(LPVOID   pParam)
在使用CreateThread时,线程的函数定义为:  DWORD  WINAPI  _yourThreadFun(LPVOID pParameter)。

两个的实质都是一样的,不过AfxBeginThread返回一个CWinThread的指针,就是说他会new一个CWinThread对象,而且这个对象是自动删除的(在线程运行结束时),给我们带来的不便就是无法获得它的状态,因为随时都有可能这个指针指向的是一个已经无效的内存区域,所以使用时(如果需要了解它的运行状况的话)首先CREATE_SUSPENDED让他挂起,然后m_bAutoDelete=FALSE,接着才ResumeThread,最后不要了delete那个指针。

CreatThread就方便多了,它返回的是一个句柄,如果你不使用CloseHandle的话就可以通过他安全的了解线程状态,最后不要的时候CloseHandle,Windows才会释放资源(线程内核对象).
下面我们就来看一下AfxBeginThread函数的内部实现:

//启动worker线程

CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,

    int nPriority, UINT nStackSize, DWORD dwCreateFlags,

    LPSECURITY_ATTRIBUTES lpSecurityAttrs)

{

         ASSERT(pfnThreadProc != NULL);

         CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);          ASSERT_VALID(pThread);

         if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,                   lpSecurityAttrs))          {                   pThread->Delete();                   return NULL;          }          VERIFY(pThread->SetThreadPriority(nPriority));          if (!(dwCreateFlags & CREATE_SUSPENDED))                   VERIFY(pThread->ResumeThread() != (DWORD)-1);          return pThread; }

//启动UI线程 CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,int nPriority, UINT nStackSize, DWORD dwCreateFlags, LPSECURITY_ATTRIBUTES lpSecurityAttrs) {

        ASSERT(pThreadClass != NULL);         ASSERT(pThreadClass->IsDerivedFrom(RUNTIME_CLASS(CWinThread)));         CWinThread* pThread = (CWinThread*)pThreadClass->CreateObject();         if (pThread == NULL)                 AfxThrowMemoryException();         ASSERT_VALID(pThread);         pThread->m_pThreadParams = NULL;         if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,                 lpSecurityAttrs))         {                 pThread->Delete();                 return NULL;         }         VERIFY(pThread->SetThreadPriority(nPriority));         if (!(dwCreateFlags & CREATE_SUSPENDED))                 VERIFY(pThread->ResumeThread() != (DWORD)-1);         return pThread; }

主要创建函数是

pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,lpSecurityAttrs))

也就是

CWinThread::CreateThread

希望本文所述对大家的VC程序设计有所帮助。

 类似资料:
  • 本文向大家介绍VC中SendMessage和PostMessage的区别,包括了VC中SendMessage和PostMessage的区别的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了VC中SendMessage和PostMessage的区别。分享给大家供大家参考。具体分析如下: 1、首先是返回值意义的区别,我们先看一下 MSDN 里的声明:   其中 4 个参数的意义是一样的,返回值类

  • 本文向大家介绍==和===、以及Object.is的区别?相关面试题,主要包含被问及==和===、以及Object.is的区别?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: (1) == 主要存在:强制转换成number,null==undefined " "==0 //true "0"==0 //true " " !="0" //true 123=="123" //true null=

  • 本文向大家介绍VC中SDK与MFC的区别浅析,包括了VC中SDK与MFC的区别浅析的使用技巧和注意事项,需要的朋友参考一下 本文浅析了vc中SDK与MFC的区别,对于初学VC的朋友有一定的学习借鉴价值,详情如下: SDK 是指Software Development Kit 软件开发包 MFC 是指Microsoft Foundation Classes 微软函数类库 因此MFC是对API函数的封

  • 本文向大家介绍du 和 df 的定义,以及区别?相关面试题,主要包含被问及du 和 df 的定义,以及区别?时的应答技巧和注意事项,需要的朋友参考一下 答案: du 显示目录或文件的大小 df 显示每个<文件>所在的文件系统的信息,默认是显示所有文件系统。(文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如 i 节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,

  • 本文向大家介绍详细分析css float 属性以及position:absolute 的区别,包括了详细分析css float 属性以及position:absolute 的区别的使用技巧和注意事项,需要的朋友参考一下 1.float 属性定义元素在哪个方向浮动。以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素

  • 我尝试了一些具有分析功能的示例,并创建了一个sql fiddle来理解分区上的count distinct by Clause,这就是我的SQLFiddle。 如果查看结果集,我会认为第三行的valcount为1,但它是2,不确定为什么会这样。