32位Windows環(huán)境下的Win32 API提供了多線程應(yīng)用程序開(kāi)發(fā)所需要的接口函數(shù),而相應(yīng)的MFC類(lèi)庫(kù)封裝了多線程編程的類(lèi),用戶在開(kāi)發(fā)時(shí)可根據(jù)應(yīng)用程序的需要和特點(diǎn)選擇相應(yīng)的工具。以下將概括歸納基于WIN32 API和MFC的多線程技術(shù),以及線程通信的實(shí)現(xiàn)方法。

WIN32 API下多線程編程

1.線程創(chuàng)建:該函數(shù)在其調(diào)用進(jìn)程的進(jìn)程空間里創(chuàng)建一個(gè)新的線程,并返回已建線程的句柄。
HANDLE CreateThread(
                                       LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                       DWORD dwStackSize,
                                       LPTHREAD_START_ROUTINE lpStartAddress,
                                       LPVOID lpParameter,
                                       DWORD dwCreationFlags,
                                       LPDWORD lpThreadId
                                       );

其中各參數(shù)說(shuō)明如下:
llpThreadAttributes:指向一個(gè) SECURITY_ATTRIBUTES 結(jié)構(gòu)的指針,該結(jié)構(gòu)決定了線程的安全屬性,一般置為 NULL;
ldwStackSize:指定了線程的堆棧深度,一般都設(shè)置為0,表示線程堆棧大小與創(chuàng)建它的線程相同;
llpStartAddress:表示新線程開(kāi)始執(zhí)行時(shí)代碼所在函數(shù)的地址,即線程的起始地址。一般情況為(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc 是線程函數(shù)名,函數(shù)原型如下:
 DWORD  WINAPI  threadfunc(LPVOID  param);
llpParameter:指定了線程執(zhí)行時(shí)傳送給線程的32位參數(shù),即線程函數(shù)的參數(shù);
ldwCreationFlags:控制線程創(chuàng)建的附加標(biāo)志,可以取兩種值。如果該參數(shù)為0,線程在被創(chuàng)建后就會(huì)立即開(kāi)始執(zhí)行;如果該參數(shù)為CREATE_SUSPENDED,則系統(tǒng)產(chǎn)生線程后,該線程處于掛起狀態(tài),并不馬上執(zhí)行,直至函數(shù)ResumeThread被調(diào)用;
llpThreadId:該參數(shù)返回所創(chuàng)建線程的ID;

DWORD WINAPI Func1(LPVOID param)
{
    cout 
<< "test" << endl;
    MessageBox(NULL, 
"test""title", MB_OK);

    
return 0;
}


int main()
{
    HANDLE p;
    DWORD a 
= 10;
    DWORD id 
= 0;

    p 
= CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Func1, &a, 0&id);
    
//WaitForSingleObject(p, INFINITE);

    
return 0;
}


2.線程懸掛和恢復(fù):創(chuàng)建新的線程后,該線程就開(kāi)始啟動(dòng)執(zhí)行。但如果在dwCreationFlags中使用了CREATE_SUSPENDED特性,線程并不馬上執(zhí)行,而是先掛起,等到調(diào)用ResumeThread后才開(kāi)始啟動(dòng)線程。

DWORD SuspendThread(HANDLE hThread);
//該函數(shù)用于掛起指定的線程,如果函數(shù)執(zhí)行成功,則線程的執(zhí)行被終止。
DWORD ResumeThread(HANDLE hThread);
//該函數(shù)用于結(jié)束線程的掛起狀態(tài),執(zhí)行線程。


3.線程優(yōu)先級(jí)操作:

int GetThreadPriority(HANDLE hThread);
//調(diào)用該函數(shù)得到線程優(yōu)先權(quán)。
BOOL SetThreadPriority(HANDLE hThread,int nPriority); 
//調(diào)用該函數(shù)來(lái)設(shè)置線程的優(yōu)先權(quán)。


4.線程退出:當(dāng)調(diào)用線程的函數(shù)返回后,線程自動(dòng)終止。

//如果需要在線程的執(zhí)行過(guò)程中終止則可調(diào)用函數(shù): 
VOID ExitThread(DWORD dwExitCode); 
//如果在線程的外面終止線程,則可調(diào)用下面的函數(shù): 
BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode); 

注意:
(1)TerminateThread函數(shù)可能會(huì)引起系統(tǒng)不穩(wěn)定,而且線程所占用的資源也不釋放。因此,一般情況下,建議不要使用該函數(shù)。
(2)如果要終止的線程是進(jìn)程內(nèi)的最后一個(gè)線程,則線程被終止后相應(yīng)的進(jìn)程也應(yīng)終止。
(3)釋放資源后,將線程HANDLE置成NULL。
(4)使用TerminateThread后,需調(diào)用CloseHandle( )函數(shù)釋放線程所占用的堆棧。



MFC下多線程編程之工作線程編程

1.線程創(chuàng)建:

CWinThread*AfxBeginThread( 
                                                AFX_THREADPROC pfnThreadProc, 
                                                LPVOID pParam,
                                                
int nPriority = THREAD_PRIORITY_NORMAL,
                                                UINT nStackSize 
= 0,
                                                DWORD dwCreateFlags 
= 0
                                                LPSECURITY_ATTRIBUTES lpSecurityAttrs 
= NULL);

各參數(shù)如下:
l參數(shù)pfnThreadProc是線程執(zhí)行體函數(shù),函數(shù)原形為: UINT ThreadFunction( LPVOID pParam)。
l參數(shù)pParam是傳遞給執(zhí)行函數(shù)的參數(shù);
l參數(shù)nPriority是線程執(zhí)行權(quán)限,可選值:
THREAD_PRIORITY_NORMAL、THREAD_PRIORITY_LOWEST、THREAD_PRIORITY_HIGHEST、THREAD_PRIORITY_IDLE。
l參數(shù)dwCreateFlags是線程創(chuàng)建時(shí)的標(biāo)志,可取值CREATE_SUSPENDED,表示線程創(chuàng)建后處于掛起狀態(tài),調(diào)用ResumeThread函數(shù)后線程繼續(xù)運(yùn)行,或者取值“0”表示線程創(chuàng)建后處于運(yùn)行狀態(tài)。
l返回值是CWinThread類(lèi)對(duì)象指針,它的成員變量m_hThread為線程句柄,在Win32 API方式下對(duì)線程操作的函數(shù)參數(shù)都要求提供線程的句柄,所以當(dāng)線程創(chuàng)建后可以使用所有Win32 API函數(shù)對(duì)pWinThread->m_Thread線程進(jìn)行相關(guān)操作。

注意:如果在一個(gè)類(lèi)對(duì)象中創(chuàng)建和啟動(dòng)線程時(shí),應(yīng)將線程函數(shù)定義成類(lèi)外的全局函數(shù)(或者類(lèi)中的靜態(tài)函數(shù)似乎也可以)。

2.線程懸掛和恢復(fù) / 優(yōu)先級(jí)操作:同上。

3.線程退出:當(dāng)調(diào)用線程的函數(shù)返回后,線程自動(dòng)終止。

//線程可以在自身內(nèi)部調(diào)用來(lái)終止自身的運(yùn)行。
void AfxEndThread(UINT nExitCode, BOOL bDelete = TRUE);
//可以在線程的外部調(diào)用來(lái)強(qiáng)行終止一個(gè)線程的運(yùn)行。
BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode );

注意:
(1)使用TerminateThread后,需調(diào)用CloseHandle( )函數(shù)釋放線程所占用的堆棧。
(2)釋放資源后,將線程HANDLE置成NULL。


進(jìn)程間通信

1.全局變量方式:
(1)進(jìn)程和線程共享全局變量,可利用該全局變量達(dá)到通信的目的。
(2)將進(jìn)程的HADNLE作為參數(shù)傳遞給線程函數(shù),然后線程可根據(jù)此HANDLE對(duì)進(jìn)程的變量進(jìn)行操作。

2.消息通信方式:

BOOL PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL PostThreadMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
顯然它們發(fā)送到的對(duì)象不同:PostMessage發(fā)消息給窗口,PostThreadMessage發(fā)消息給線程。且當(dāng)PostThreadMessage的hWnd = NULL時(shí),表明該消息傳遞給當(dāng)前線程本身。 
BOOL   PostMessage(   UINT   message,   WPARAM   wParam   =   0,   LPARAM   lParam   =0   );  
返回值如果公布了消息,則返回非零值;否則返回0。   
參數(shù)message指定了要公布的消息。  
wParam指定了附加的消息信息。這個(gè)參數(shù)的內(nèi)容依賴(lài)于要公布的消息。  
lParam指定了附加的消息信息。這個(gè)參數(shù)的內(nèi)容依賴(lài)于要公布的消息。  
說(shuō)明:這個(gè)函數(shù)將一個(gè)消息放入窗口的消息隊(duì)列,然后直接返回,并不等待對(duì)應(yīng)的窗口處理消息。消息隊(duì)列中的消息是通過(guò)調(diào)用Windows的GetMessage或PeekMessage函數(shù)來(lái)獲得的。可以通過(guò)Windows的PostMessage函數(shù)來(lái)訪問(wèn)其它應(yīng)用程序。   
   
BOOL   PostThreadMessage(   UINT   message   ,   WPARAM   wParam,   LPARAMlParam   );返回值如果成功,則返回非零值;否則返回0。  
參數(shù)message用戶自定義消息的ID。  
wParam第一個(gè)消息參數(shù)。  
lParam第二個(gè)消息參數(shù)。  
說(shuō)明:調(diào)用這個(gè)函數(shù)以向其它CWinThread對(duì)象發(fā)送一個(gè)用戶自定義消息。發(fā)送的消息通過(guò)消息映射宏ON_THREAD_MESSAGE被映射到適當(dāng)?shù)南⑻幚砗瘮?shù)。   

3.同步方式:具體參見(jiàn)http://www.shnenglu.com/andxie99/archive/2006/10/10/13517.html