32位Windows環境下的Win32 API提供了多線程應用程序開發所需要的接口函數,而相應的MFC類庫封裝了多線程編程的類,用戶在開發時可根據應用程序的需要和特點選擇相應的工具。以下將概括歸納基于WIN32 API和MFC的多線程技術,以及線程通信的實現方法。
WIN32 API下多線程編程1.線程創建:該函數在其調用進程的進程空間里創建一個新的線程,并返回已建線程的句柄。
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
其中各參數說明如下:
llpThreadAttributes:指向一個 SECURITY_ATTRIBUTES 結構的指針,該結構決定了線程的安全屬性,一般置為 NULL;
ldwStackSize:指定了線程的堆棧深度,一般都設置為0,表示線程堆棧大小與創建它的線程相同;
llpStartAddress:表示新線程開始執行時代碼所在函數的地址,即線程的起始地址。一般情況為(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc 是線程函數名,函數原型如下:
DWORD WINAPI threadfunc(LPVOID param);
llpParameter:指定了線程執行時傳送給線程的32位參數,即線程函數的參數;
ldwCreationFlags:控制線程創建的附加標志,可以取兩種值。如果該參數為0,線程在被創建后就會立即開始執行;如果該參數為CREATE_SUSPENDED,則系統產生線程后,該線程處于掛起狀態,并不馬上執行,直至函數ResumeThread被調用;
llpThreadId:該參數返回所創建線程的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.線程懸掛和恢復:創建新的線程后,該線程就開始啟動執行。但如果在dwCreationFlags中使用了CREATE_SUSPENDED特性,線程并不馬上執行,而是先掛起,等到調用ResumeThread后才開始啟動線程。
DWORD SuspendThread(HANDLE hThread);
//該函數用于掛起指定的線程,如果函數執行成功,則線程的執行被終止。
DWORD ResumeThread(HANDLE hThread);
//該函數用于結束線程的掛起狀態,執行線程。
3.線程優先級操作:
int GetThreadPriority(HANDLE hThread);
//調用該函數得到線程優先權。
BOOL SetThreadPriority(HANDLE hThread,int nPriority);
//調用該函數來設置線程的優先權。
4.線程退出:當調用線程的函數返回后,線程自動終止。
//如果需要在線程的執行過程中終止則可調用函數:
VOID ExitThread(DWORD dwExitCode);
//如果在線程的外面終止線程,則可調用下面的函數:
BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);
注意:
(1)TerminateThread函數可能會引起系統不穩定,而且線程所占用的資源也不釋放。因此,一般情況下,建議不要使用該函數。
(2)如果要終止的線程是進程內的最后一個線程,則線程被終止后相應的進程也應終止。
(3)釋放資源后,將線程HANDLE置成NULL。
(4)使用TerminateThread后,需調用CloseHandle( )函數釋放線程所占用的堆棧。
MFC下多線程編程之工作線程編程
1.線程創建:
CWinThread*AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
各參數如下:
l參數pfnThreadProc是線程執行體函數,函數原形為: UINT ThreadFunction( LPVOID pParam)。
l參數pParam是傳遞給執行函數的參數;
l參數nPriority是線程執行權限,可選值:
THREAD_PRIORITY_NORMAL、THREAD_PRIORITY_LOWEST、THREAD_PRIORITY_HIGHEST、THREAD_PRIORITY_IDLE。
l參數dwCreateFlags是線程創建時的標志,可取值CREATE_SUSPENDED,表示線程創建后處于掛起狀態,調用ResumeThread函數后線程繼續運行,或者取值“0”表示線程創建后處于運行狀態。
l返回值是CWinThread類對象指針,它的成員變量m_hThread為線程句柄,在Win32 API方式下對線程操作的函數參數都要求提供線程的句柄,所以當線程創建后可以使用所有Win32 API函數對pWinThread->m_Thread線程進行相關操作。
注意:如果在一個類對象中創建和啟動線程時,應將線程函數定義成類外的全局函數(或者類中的靜態函數似乎也可以)。
2.線程懸掛和恢復 / 優先級操作:同上。
3.線程退出:當調用線程的函數返回后,線程自動終止。
//線程可以在自身內部調用來終止自身的運行。
void AfxEndThread(UINT nExitCode, BOOL bDelete = TRUE);
//可以在線程的外部調用來強行終止一個線程的運行。
BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode );
-
注意:
(1)使用TerminateThread后,需調用CloseHandle( )函數釋放線程所占用的堆棧。
(2)釋放資源后,將線程HANDLE置成NULL。
進程間通信
1.全局變量方式:
(1)進程和線程共享全局變量,可利用該全局變量達到通信的目的。
(2)將進程的HADNLE作為參數傳遞給線程函數,然后線程可根據此HANDLE對進程的變量進行操作。
2.消息通信方式:
BOOL PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL PostThreadMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

顯然它們發送到的對象不同:PostMessage發消息給窗口,PostThreadMessage發消息給線程。且當PostThreadMessage的hWnd = NULL時,表明該消息傳遞給當前線程本身。
BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam =0 );
返回值如果公布了消息,則返回非零值;否則返回0。
參數message指定了要公布的消息。
wParam指定了附加的消息信息。這個參數的內容依賴于要公布的消息。
lParam指定了附加的消息信息。這個參數的內容依賴于要公布的消息。
說明:這個函數將一個消息放入窗口的消息隊列,然后直接返回,并不等待對應的窗口處理消息。消息隊列中的消息是通過調用Windows的GetMessage或PeekMessage函數來獲得的。可以通過Windows的PostMessage函數來訪問其它應用程序。
BOOL PostThreadMessage( UINT message , WPARAM wParam, LPARAMlParam );返回值如果成功,則返回非零值;否則返回0。
參數message用戶自定義消息的ID。
wParam第一個消息參數。
lParam第二個消息參數。
說明:調用這個函數以向其它CWinThread對象發送一個用戶自定義消息。發送的消息通過消息映射宏ON_THREAD_MESSAGE被映射到適當的消息處理函數。
3.同步方式:具體參見http://www.shnenglu.com/andxie99/archive/2006/10/10/13517.html。