VC啟動一個新執行緒的三種方法

黨偉_90發表於2018-05-06

第一種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);

示例:

  1. UINT  myproc(LPVOID  lParam)  
  2. {  
  3. CITTDlg *pWnd = (CITTDlg *)lParam;         //將視窗指標賦給無型別指標  
  4. pWnd->KMeansSegment();                         //要執行的函式  
  5. return 1;  
  6. }  
  7.   
  8. void CITTDlg::KMeansSegment()  
  9. {  
  10. // 主要處理函式在這裡寫  
  11. }  
  12.   
  13. void CITTDlg::OnKMeansSegment()             //按鈕點選執行  
  14. {  
  15.   
  16. AfxBeginThread(myproc, (LPVOID)this);//啟動新的執行緒  
  17.   
  18. }  

注意,工作者執行緒的函式必須是全域性函式或靜態成員函式,不能是普通的成員函式。


第二種CreateThread()

函式原型為:HANDLE CreateThread(
                           NULL,  // 沒有安全描述符
                           0,  // 預設執行緒棧的大小
                           MyThreadProc,  // 執行緒函式指標,即函式名
                           (LPVOID)&n,  // 傳遞引數
                           NULL,  // 沒有附加屬性
                           NULL  // 不需要獲得執行緒號碼
                           );

CreatThread,它返回的是一個控制程式碼;如果不需要再監視執行緒,則用CloseHandle()關閉執行緒控制程式碼。
執行緒的函式必須定義為: DWORD WINAPI   MyThreadProc(LPVOID pParameter);

下面演示多執行緒操作控制元件,點選一個Button然後執行一個執行緒,將字串顯示在CEdit控制元件裡面;
示例:

  1. .h標頭檔案  
  2.   
  3. struct hS  
  4.     {  
  5.         CString Tmp;  
  6.         CTestDlg *hWnd;  
  7.     };//定義全域性結構體,用來傳遞自定義訊息  
  8.   
  9. DWORD WINAPI ThreadProc(LPVOIDlpParam);//執行緒函式宣告,全域性函式  
  10.   
  11. public:  
  12.     CString chtmp;  
  13.     struct hS    *hTmp;  
  14.   
  15. protected:  
  16.    HANDLE m_hThread;//執行緒控制程式碼  
  17.    CEdit  m_Edit;  
  18.   
  19. .cpp實現檔案  
  20.   
  21. //執行緒執行函式  
  22.   
  23. DWORD WINAPI   ThreadProc(LPVOID lpParam)  
  24. {  
  25. //在這裡寫處理函式  
  26.         struct hS *Tmp2;  
  27.         Tmp2 = (hS*)lpParam;  
  28. // 操作:  
  29.        Tmp2->hWnd->m_Edit.SetWindowText( (LPTSTR)Tmp2->Tmp );  
  30. }  
  31.   
  32. void CTestDlg::OnBnClickedButton1()  
  33. {  
  34.     hTmp->Tmp = chtmp;  
  35.     hTmp->hWnd = this;//關鍵是把this指標傳進去  
  36.    m_hThread =CreateThread(NULL,0,ThreadProc,hTmp,0,NULL);//建立新執行緒  
  37.    CloseHandle(m_hThread );  
  38. }  

用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的執行庫函式。


版權宣告: https://blog.csdn.net/u014568921/article/details/44262645

相關文章