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,如需轉載請自行聯系原作者