天天看点

AfxBeginThread和AfxEndThread及线程资源分配和释放

 AfxBeginThread动态创建CWinThread(或派生类)线程对象,并分配相关资源.

AfxEndThread会释放线程资源和CWinThread(或派生类)线程对象.

下面这个过程的分析,这里仅仅给出简单代码用于说明问题.

首先看一下创建线程的函数.

CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass, 

    int nPriority, UINT nStackSize, DWORD dwCreateFlags, 

    LPSECURITY_ATTRIBUTES lpSecurityAttrs) 

  ...... 

    // 创建线程对象.CreateObject()函数内部有new操作符. 

    CWinThread* pThread = (CWinThread*)pThreadClass->CreateObject(); 

    // 创建线程. 

    pThread->m_pThreadParams = NULL; 

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

    return pThread; 

注意红色的文字,CreateObject()函数内适用new操作符创建线程对象CWinThread或者其派生类对象.

下面是CreateThread函数.

BOOL CWinThread::CreateThread(DWORD dwCreateFlags, UINT nStackSize, 

    ... ... 

    // create the thread (it may or may not start to run) 

    m_hThread = (HANDLE)(ULONG_PTR)_beginthreadex(lpSecurityAttrs, nStackSize,   

    &_AfxThreadEntry, &startup, dwCreateFlags | CREATE_SUSPENDED, (UINT*)&m_nThreadID); 

    return TRUE; 

这个函数调用_beginthreadex创建线程.

注意线程回调函数_AfxThreadEntry,下面是其部分代码.

UINT APIENTRY _AfxThreadEntry(void* pParam) 

    _AFX_THREAD_STARTUP* pStartup = (_AFX_THREAD_STARTUP*)pParam; 

    CWinThread* pThread = pStartup->pThread; 

    // forced initialization of the thread 

    AfxInitThread(); 

  ... ... 

    AfxEndThread(nResult); 

    return 0;   // not reached 

这个函数调用了函数AfxEndThread().从这里可以看出,若CWinThread(获取派生类)对象如果能够从线程函数正常返回,一定会调用AfxEndThread()函数. 

下面是AfxEndThread函数的代码.

void AFXAPI AfxEndThread(UINT nExitCode, BOOL bDelete) 

    pThread->Delete(); 

    // allow cleanup of any thread local objects 

    AfxTermThread(); 

    // allow C-runtime to cleanup, and exit the thread 

    _endthreadex(nExitCode); 

void CWinThread::Delete() 

    // delete thread if it is auto-deleting 

    if (m_bAutoDelete) 

        delete this; 

从注释和代码可以看出,该函数用来释放资源和CWinThread对象(delete this).

从上面的分析可以看出, 函数调用AfxBeginThread可以动态创建CWinThread(或派生类)对象,如果能够保证程序正常从线程回调函数退出(也就是CWinThread::Run()函数),就能够保证线程对象及资源被正确释放.

本文转自jetyi51CTO博客,原文链接:http://blog.51cto.com/jetyi/1074783,如需转载请自行联系原作者

继续阅读