第一種AfxBeginThread()
用AfxBeginThread()函數來建立一個新線程來執行任務,工作者線程的AfxBeginThread的原型如下:
CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,
LPVOID lParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);//用于建立工作者線程
傳回值: 成功時傳回一個指向新線程的線程對象的指針,否則NULL。
pfnThreadProc : 線程的入口函數,聲明一定要如下: UINT MyThreadFunction(LPVOID pParam),不能設定為NULL;
pParam : 傳遞入線程的參數,注意它的類型為:LPVOID,是以我們可以傳遞一個結構體入線程.
nPriority : 線程的優先級,一般設定為 0 .讓它和主線程具有共同的優先級.
nStackSize : 指定新建立的線程的棧的大小.如果為 0,新建立的線程具有和主線程一樣的大小的棧
dwCreateFlags : 指定建立線程以後,線程有怎麼樣的标志.可以指定兩個值:
CREATE_SUSPENDED : 線程建立以後,會處于挂起狀态,直到調用:ResumeThread
0 : 建立線程後就開始運作.
lpSecurityAttrs : 指向一個 SECURITY_ATTRIBUTES 的結構體,用它來标志新建立線程的安全性.如果為 NULL,
那麼新建立的線程就具有和主線程一樣的安全性.
如果要線上程内結束線程,可以線上程内調用 AfxEndThread.
一般直接用AfxBeginThread(ThreadProc,this);
示例:
UINT myproc(LPVOID lParam)
{
CITTDlg *pWnd = (CITTDlg *)lParam; //将視窗指針賦給無類型指針
pWnd->KMeansSegment(); //要執行的函數
return 1;
}
void CITTDlg::KMeansSegment()
{
// 主要處理函數在這裡寫
}
void CITTDlg::OnKMeansSegment() //按鈕點選執行
{
AfxBeginThread(myproc, (LPVOID)this);//啟動新的線程
}
注意,工作者線程的函數必須是全局函數或靜态成員函數,不能是普通的成員函數。
第二種CreateThread()
函數原型為:HANDLE CreateThread(
NULL, // 沒有安全描述符
0, // 預設線程棧的大小
MyThreadProc, // 線程函數指針,即函數名
(LPVOID)&n, // 傳遞參數
NULL, // 沒有附加屬性
NULL // 不需要獲得線程号碼
);
CreatThread,它傳回的是一個句柄;如果不需要再監視線程,則用CloseHandle()關閉線程句柄。
線程的函數必須定義為: DWORD WINAPI MyThreadProc(LPVOID pParameter);
下面示範多線程操作控件,點選一個Button然後運作一個線程,将字元串顯示在CEdit控件裡面;
示例:
.h頭檔案
struct hS
{
CString Tmp;
CTestDlg *hWnd;
};//定義全局結構體,用來傳遞自定義消息
DWORD WINAPI ThreadProc(LPVOIDlpParam);//線程函數聲明,全局函數
public:
CString chtmp;
struct hS *hTmp;
protected:
HANDLE m_hThread;//線程句柄
CEdit m_Edit;
.cpp實作檔案
//線程執行函數
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
//在這裡寫處理函數
struct hS *Tmp2;
Tmp2 = (hS*)lpParam;
// 操作:
Tmp2->hWnd->m_Edit.SetWindowText( (LPTSTR)Tmp2->Tmp );
}
void CTestDlg::OnBnClickedButton1()
{
hTmp->Tmp = chtmp;
hTmp->hWnd = this;//關鍵是把this指針傳進去
m_hThread =CreateThread(NULL,0,ThreadProc,hTmp,0,NULL);//建立新線程
CloseHandle(m_hThread );
}
用CreateThread()函數建立線程将傳回一個線程句柄,通過該句柄你可以控制和操作該線程,當你不用時可以一建立該線程後就關閉該句柄,有專門的函CloseHandle()。關閉句柄不代表關閉線程,隻是你不能在外部控制該線程(比如,提前結束,更改優先級等)。線上程結束後,系統将自動清理線程資源,但并不自動關閉該句柄,是以線程結束後要記得關閉該句柄。
第三種_beginthread()
函數原型為:intptr_t _beginthread(
void( *start_address )( void * ), //指向新線程調用的函數的起始位址
unsigned stack_size, //堆棧大小,設定0為系統預設值
void *arglist //傳遞給線程函數的參數,沒有則為NULL
);
傳回值:
假如成功,函數将會傳回一個新線程的句柄,使用者可以像這樣聲明一個句柄變量存儲傳回值:
HANDLE hStdOut = _beginthread( CheckKey, 0, NULL )。如果失敗_beginthread将傳回-1。 所在庫檔案:
#include <process.h>
線程函數的定義:
對于_beginthread()建立的線程,其線程函數定義為:
void ThreadPro(void * pArguments );
_beginthreadex()為_beginthread()的更新版。
總結: AfxBeginThread是MFC的全局函數,是對CreateThread的封裝。 CreateThread是Win32 API函數,AfxBeginThread最終要調到CreateThread。而_beginthread是C的運作庫函數。