MFC多线程的创建,包括工作线程和用户界面线程

MFC多线程的创建

1.MFC多线程简介

MFC对多线程进行了一层简单的封装,Visual C++中每个线程都是从CWinThread类继承而来的。每一个应用程序的执行都有一个主线程,这个主线程也是从CWinThread类继承而来的。可以利用CWinThread对象创建应用程序执行的其它线程。

MFC用CWinThread对象来表示所有线程。利用MFC可以创建两种线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等。用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。但对于Win32API编程而言,这两种线程是没有区别的,它们都只需线程的启动地址即可启动线程来执行任务。

2.MFC多线程基础

为了深入了解MFC下创建线程的方法,我们先深入学习一下CWinThread类。CWinThread类在MFC类结构中的位置如下图所示:

图1:CWinThread类在mfc类结构中的位置

详细的MFC类结构图请参考MSDN: http://msdn.microsoft.com/zh-cn/library/ws8s10w4(VS.90).aspx

首先看一下类CWinThread的声明。类CWinThread的声明在afxwin.h中:

/

Class CWinThread :publicCCmdTarget

{

    DECLARE_DYNAMIC(CWinThread)

public:

//构造函数

    CWinThread();

//用来具体创建线程的函数

    BOOL CreateThread(DWORDdwCreateFlags = 0,UINTnStackSize = 0,

       LPSECURITY_ATTRIBUTES lpSecurityAttrs= NULL);

// Attributes

//主窗口,(通常使用AfxGetApp()->m_pMainWnd可以得到)

    CWnd* m_pMainWnd;       // main window(usually same AfxGetApp()->m_pMainWnd)

//活动窗口,可能不是主窗口

    CWnd* m_pActiveWnd;     // active mainwindow (may not be m_pMainWnd)

    BOOL m_bAutoDelete;     // enables'delete this' after thread termination

    // only valid while running

//该线程的句柄

    HANDLE m_hThread;       // thisthread's HANDLE

    operator HANDLE() const;

//该线程的ID

    DWORD m_nThreadID;      // thisthread's ID

//线程优先级

    int GetThreadPriority();

    BOOL SetThreadPriority(int nPriority);

// Operations

//挂起线程

    DWORD SuspendThread();

//启动线程

    DWORD ResumeThread();

//发送线程消息

    BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);

// Overridables

    // 线程初始化,每个应用程序都可以重载该函数

    virtual BOOL InitInstance();

    // running and idle processing

    virtual int Run();

    virtual BOOL PreTranslateMessage(MSG*pMsg);

    virtual BOOL PumpMessage();    // low level message pump

    virtual BOOL OnIdle(LONGlCount);// return TRUEif more idle processing

    virtual BOOL IsIdleMessage(MSG*pMsg); // checks for special messages

    // thread termination

    virtual int ExitInstance(); //default will 'delete this'

    // Advanced: exception handling

    virtual LRESULT ProcessWndProcException(CException*e,constMSG*pMsg);

    // Advanced: handling messages sent to message filter hook

    virtual BOOL ProcessMessageFilter(intcode,LPMSGlpMsg);

    // Advanced: virtual access to m_pMainWnd

    virtual CWnd* GetMainWnd();

// Implementation

public:

    virtual ~CWinThread();

#ifdef _DEBUG

    virtual void AssertValid() const;

    virtual void Dump(CDumpContext&dc)const;

#endif

    void CommonConstruct();

    virtual void Delete();

       // 'delete this' only if m_bAutoDelete == TRUE

public:

    // constructor used by implementation of AfxBeginThread

    CWinThread(AFX_THREADPROCpfnThreadProc,LPVOIDpParam);

    // valid after construction

    LPVOID m_pThreadParams;// generic parameters passed to starting function

    AFX_THREADPROC m_pfnThreadProc;

    // set after OLE is initialized

    void (AFXAPI*m_lpfnOleTermOrFreeLib)(BOOL,BOOL);

    COleMessageFilter* m_pMessageFilter;

protected:

    BOOL DispatchThreadMessageEx(MSG* msg);  // helper

    void DispatchThreadMessage(MSG* msg);  // obsolete

};

/

有些函数是不是很眼熟呀,在前面的文章中已经介绍和使用过啦。MFC类就是这样的,它无非就是简单封装一些API函数,并添加一些自己的函数而构成的。不用MFC我们照样可以编写很优秀的程序,MFC的宗旨就是简化程序设计,让你可以很容易入门和简单的使用,也催生了大量的程序员。但对喜欢刨根问底的朋友却是一道很厚的墙

下面几个函数是多线程编程中经常用到的几个全局函数:

//创建工作线程

CWinThread* AFXAPIAfxBeginThread(

AFX_THREADPROC pfnThreadProc,//线程函数

 LPVOID pParam,//传给线程函数的参数

int nPriority =THREAD_PRIORITY_NORMAL,//线程的优先级

UINT nStackSize = 0,//堆栈大小

DWORD dwCreateFlags = 0,//创建起始状态标志

   LPSECURITY_ATTRIBUTES lpSecurityAttrs= NULL//线程的安全属性

);

//创建用户界面线程

CWinThread* AFXAPIAfxBeginThread(

CRuntimeClass* pThreadClass,//从CWinThread派生的类的RUNTIME_CLASS

int nPriority =THREAD_PRIORITY_NORMAL,//线程的优先级

   UINT nStackSize = 0,// 堆栈大小

DWORD dwCreateFlags = 0,// 创建起始状态标志

 LPSECURITY_ATTRIBUTESlpSecurityAttrs =NULL//线程的安全属性

);

//获取线程对象

CWinThread* AFXAPIAfxGetThread();

//获取当前消息

MSG* AFXAPIAfxGetCurrentMessage();

//结束线程执行

void AFXAPIAfxEndThread(UINTnExitCode,BOOLbDelete =TRUE);

//初始化线程

void AFXAPIAfxInitThread();

//终止线程执行

void AFXAPIAfxTermThread(HINSTANCEhInstTerm =NULL);

仔细阅读以上类的说明能学到不少东西:

(1)   CWinThead类通过CreateThread()成员函数来创建线程,这个函数的声明和Win32APICreateThread()的参数相似

(2)每个函数在运行后都有一个句柄和ID号。

(3)通过设置属性m_bAutoDelete,可决定线程在运行结束后线程对象是否自动删除,它的访问权限是public型的,可以直接进行设置。一般情况下,线程对象的生命周期和线程的生命周期一致。如果你想改变线程对象的生命周期,可设置该属性为FALSE。

(4)MFC下的多线程仍然支持线程的挂起和启动。

(5)具有PreTranslateMessage()、PumpMessage()等函数,供用户界面线程的消息机制使用。

在MFC中实际上是调用AfxBeginThread()函数来创建线程的。那么为什么不直接使用::CreateThread()_beginthread()函数来创建线程呢?只要看一下CWinThread类的实现中的相关代码就明白了。在thrdcore.cpp文件中的相关代码如下:

==========================================================================================================

CWinThread* AFXAPI AfxGetThread()

{

    // check for current thread in module thread state

    AFX_MODULE_THREAD_STATE* pState= AfxGetModuleThreadState();

    CWinThread* pThread= pState->m_pCurrentWinThread;

    return pThread;

}


MSG* AFXAPI AfxGetCurrentMessage()

{

  _AFX_THREAD_STATE* pState= AfxGetThreadState();

  ASSERT(pState);

  return &(pState->m_msgCur);

}


CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,int nPriority,UINT nStackSize, DWORD dwCreateFlags,

    LPSECURITY_ATTRIBUTESlpSecurityAttrs)

{

#ifndef _MT

    pfnThreadProc;

    pParam;

    nPriority;

    nStackSize;

    dwCreateFlags;

    lpSecurityAttrs;

    return NULL;

#else

    ASSERT(pfnThreadProc!=NULL);

    CWinThread* pThread=DEBUG_NEWCWinThread(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;

#endif //!_MT)

}


CWinThread* AFXAPI AfxBeginThread(CRuntimeClass*pThreadClass,

    int nPriority, UINT nStackSize,DWORD dwCreateFlags,

   

  • 60
    点赞
  • 196
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值