?? thrdcore.cpp
字號:
#include "_afxwin.h"
#include "_afxtls_.h"
#include <process.h>
#include <stdio.h>
struct _AFX_THREAD_STARTUP
{
CWinThread* pThread; // 控制新線程的CWinThread對象的指針
HANDLE hEvent; // 此事件在線程初始化完畢后將被觸發
HANDLE hEvent2; // 此事件在創建線程從CreateThread函數返回時將被觸發
BOOL bError; // 指示線程是否初始化成功
};
UINT __stdcall _AfxThreadEntry(void* pParam)
{
_AFX_THREAD_STARTUP* pStartup = (_AFX_THREAD_STARTUP*)pParam;
CWinThread* pThread = pStartup->pThread;
try
{
// 設置新線程的狀態
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
pState->m_pCurrentWinThread = pThread;
}
catch(...)
{
// 如果try塊有異常拋出,此處的代碼將被執行
pStartup->bError = TRUE;
::SetEvent(pStartup->hEvent);
AfxEndThread((UINT)-1, FALSE);
}
// 調用下面的SetEvent函數后,pStartup所指向的內存空間就有可能被父線程銷毀,
// 所以要保存hEvent2的值
HANDLE hEvent2 = pStartup->hEvent2;
// 允許父線程從CWinThread::CreateThread函數返回
::SetEvent(pStartup->hEvent);
// 等待父線程中CWinThread::CreateThread函數的代碼執行完畢
::WaitForSingleObject(hEvent2, INFINITE);
::CloseHandle(hEvent2);
// 調用用戶指定的線程函數
DWORD nResult = 0;
if(pThread->m_pfnThreadProc)
nResult = (*pThread->m_pfnThreadProc)(pThread->m_pThreadParams);
// 結束線程
AfxEndThread(nResult);
return 0;
}
CWinThread* AfxGetThread()
{
// 返回當前線程CWinThread對象的指針
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
return pState->m_pCurrentWinThread;
}
void AfxEndThread(UINT nExitCode, BOOL bDelete)
{
// 釋放當前CWinThread對象占用的內存
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
CWinThread* pThread = pState->m_pCurrentWinThread;
if (pThread != NULL)
{
if (bDelete)
pThread->Delete();
pState->m_pCurrentWinThread = NULL;
}
// 釋放線程局部存儲占用的內存
if (_afxThreadData != NULL)
_afxThreadData->DeleteValues(NULL, FALSE);
// 結束此線程的運行
_endthreadex(nExitCode);
}
CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
int nPriority, UINT nStackSize, DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
// 為新線程創建一個CWinThead類的對象
CWinThread* pThread = new CWinThread(pfnThreadProc, pParam);
// 創建線程,并掛起
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
// 設置新線程的優先級
pThread->SetThreadPriority(nPriority);
// 如果沒有指定CREATE_SUSPENDED標記,則喚醒線程
if (!(dwCreateFlags & CREATE_SUSPENDED))
pThread->ResumeThread();
return pThread;
}
//----------------- CWinThread類--------------------//
void CWinThread::CommonConstruct ()
{
m_hThread = NULL;
m_nThreadID = 0;
m_bAutoDelete = TRUE;
}
CWinThread::CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam)
{
m_pfnThreadProc = pfnThreadProc;
m_pThreadParams = pParam;
CommonConstruct();
}
CWinThread::CWinThread()
{
m_pThreadParams = NULL;
m_pfnThreadProc = NULL;
CommonConstruct();
}
CWinThread::~CWinThread()
{
// 釋放線程內核對象句柄
if (m_hThread != NULL)
CloseHandle(m_hThread);
// 清除線程的狀態
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
if (pState->m_pCurrentWinThread == this)
pState->m_pCurrentWinThread = NULL;
}
BOOL CWinThread::CreateThread(DWORD dwCreateFlags, UINT nStackSize,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
// 為線程的初始化定義變量startup
_AFX_THREAD_STARTUP startup; memset(&startup, 0, sizeof(startup));
startup.pThread = this;
startup.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
startup.hEvent2 = ::CreateEvent(NULL, TRUE, FALSE, NULL);
// 創建一個初始狀態為不可調度的線程(掛起)
m_hThread = (HANDLE)_beginthreadex(lpSecurityAttrs, nStackSize,
&_AfxThreadEntry, &startup, dwCreateFlags | CREATE_SUSPENDED, (UINT*)&m_nThreadID);
if (m_hThread == NULL)
return FALSE;
// 恢復線程的執行,并等待線程初始化完畢
ResumeThread();
::WaitForSingleObject(startup.hEvent, INFINITE);
::CloseHandle(startup.hEvent);
// 如果用戶創建的是一個掛起的線程,我們就暫停線程的運行
if (dwCreateFlags & CREATE_SUSPENDED)
::SuspendThread(m_hThread);
// 如果線程在初始化時出錯,釋放所有資源
if (startup.bError)
{
::WaitForSingleObject(m_hThread, INFINITE);
::CloseHandle(m_hThread);
m_hThread = NULL;
::CloseHandle(startup.hEvent2);
return FALSE;
}
// 通知線程繼續運行
::SetEvent(startup.hEvent2);
return TRUE;
}
void CWinThread::Delete()
{
// 如果指定了自動清除的話,刪除this指針
if (m_bAutoDelete)
delete this;
}
UINT MyFunc(LPVOID lpParam)
{
printf(" Thread Identify: %d \n", AfxGetThread()->m_nThreadID);
return 0;
}
void main()
{
for(int i=0; i<10; i++)
{
AfxBeginThread(MyFunc, NULL);
}
system("pause");
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -