欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ AfxBeginThread的介紹/基本用法

 更新時間:2015年06月29日 10:54:13   投稿:hebedich  
這篇文章主要簡單介紹了C++ AfxBeginThread的基本用法,十分的細致,有需要的小伙伴可以參考下。

AfxBeginThread 

   用戶界面線程和工作者線程都是由AfxBeginThread創(chuàng)建的。現(xiàn)在,考察該函數(shù):MFC提供了兩個重載版的AfxBeginThread,一個用于用戶界面線程,另一個用于工作者線程,分別有如下的原型和過程:

用戶界面線程的AfxBeginThread
用戶界面線程的AfxBeginThread的原型如下:

CWinThread* AFXAPI AfxBeginThread(
CRuntimeClass* pThreadClass,
int nPriority,
UINT nStackSize,
DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)

其中:
參數(shù)1是從CWinThread派生的RUNTIME_CLASS類;
參數(shù)2指定線程優(yōu)先級,如果為0,則與創(chuàng)建該線程的線程相同;
參數(shù)3指定線程的堆棧大小,如果為0,則與創(chuàng)建該線程的線程相同;
參數(shù)4是一個創(chuàng)建標識,如果是CREATE_SUSPENDED,則在懸掛狀態(tài)創(chuàng)建線程,在線程創(chuàng)建后線程掛起,否則線程在創(chuàng)建后開始線程的執(zhí)行。
參數(shù)5表示線程的安全屬性,NT下有用。

工作者線程的AfxBeginThread
工作者線程的AfxBeginThread的原型如下:

CWinThread* AFXAPI AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority,
UINT nStackSize,
DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)

其中:
參數(shù)1  線程的入口函數(shù),聲明一定要如下: UINT MyThreadFunction( LPVOID pParam );
參數(shù)2 傳遞入線程的參數(shù),注意它的類型為:LPVOID,所以我們可以傳遞一個結構體入線程.
參數(shù)3、4、5分別指定線程的優(yōu)先級、堆棧大小、創(chuàng)建標識、安全屬性,含義同用戶界面線程。

附錄A:

結束線程的兩種方式
     當你在后臺用線程來打印一些圖形時.有時在打印一部分后,你希望可以停下來,那么此如何讓線程停止呢.下

面會詳細的向你解釋要結束線程的兩種方式

     1 : 這是最簡單的方式,也就是讓線程函數(shù)執(zhí)行完成,此時線程正常結束.它會返回一個值,一般0是成功結束,

當然你可以定義自己的認為合適的值來代表線程成功執(zhí)行.在線程內(nèi)調(diào)用AfxEndThread將會直接結束線程,此時線程的一切資源都會被回收.

     2 : 如果你想讓別一個線程B來結束線程A,那么,你就需要在這兩個線程中傳遞信息.不管是工作者線程還是界面線程,如果你想在線程結束后得到它的確結果,那么你可以調(diào)用     ::GetExitCodeThread函數(shù)

還是老師的那個項目,以前由于計算量太大,導致程序經(jīng)常出現(xiàn)假死的現(xiàn)象,因為程序只有一個線程,該線程主要用于處理計算上了,而對于消息隊列的響應被忽略了。因此解決的辦法就是用兩個線程,一個線程用于計算,一個線程用于處理消息。

      到網(wǎng)上找了一些資料,發(fā)現(xiàn)在MFC中把線程分為兩類,一類為界面線程,一類為工作線程。兩者的區(qū)別在于前都能夠處理消息響應,而后者則不能。對于該項目來說,只要把計算的過程放到一個工作線程里來進行就可以了。

    現(xiàn)在先試一下,我新建了一個對話框,上面添加兩個按鈕,一個是start 一個是dialog。前者用于開始計算,而后者則彈出一個消息框。然后向該對話框里面添加一個死循環(huán)的函數(shù)

UINT CMultithreadDlg::jisuan(LPVOID lpParam)
{
int i = 1;
for (;;)
{
  i+=i;
}
return 0;
}

    然后在start按鈕的響應函數(shù)上添加上jisuan(NULL);即可,現(xiàn)在運行程序,按下start按鈕后,可以看到CPU使用率漲到了100%,這個時候再按dialog按鈕無反應,拖動關閉窗口均無效。這就是前面提到的假死現(xiàn)象(實際上是真死,因為死循環(huán)了,如果不是死循環(huán),而只是計算量太大才是假死)。

    下面用多線程的方法來解決,在start按鈕的響應函數(shù)改為

CWinThread* mythread = AfxBeginThread(
  jisuan,
  NULL,
  THREAD_PRIORITY_NORMAL,
  0,
  0,
  NULL
  );

    運行,結果發(fā)現(xiàn)有錯error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'unsigned int (void *)' Generating Code...
我就納悶了,函數(shù)指針是對的啊,原來 線程函數(shù)可以且必須是全局函數(shù)或者是靜態(tài)成員函數(shù)。
所以我們在線程函數(shù)的聲明中改為 static UINT jisuan(LPVOID lpParam);即可,然后運行程序,這時點擊start,待CPU漲至100%后,點擊dialog,彈出對話框了,拖動、關閉窗口均沒問題了。

     其實上面的那個AfxBeginThread,除前面兩個參數(shù)外,后面的都是默認參數(shù),可以省略。而必須有的這兩個參數(shù),一個是線程函數(shù)的指針,一個是傳遞給這個函數(shù)的參數(shù)。實際中我們經(jīng)常這樣用 AfxBeginThread(ThreadProc,this);//把this傳過去,就可以調(diào)用類的成員了. 這樣線程函數(shù)就可以使用和操作類的成員了。千萬要注意線程函數(shù)是靜態(tài)類函數(shù)成員。

    線程是創(chuàng)建了,但是如果中途要暫停該怎么做呢?

    我們在創(chuàng)建線程的時候獲得了一個CWinThread的指針,這是一個指向線程對象的指針,CWinThread類里面就有暫停與恢復的函數(shù),下面我就演示一下。

在原來的程序上進行改動。向對話框類里面添加一個CWinThread* 的成員變量,不用初始化為NULL,這樣會報錯的,因為它只能通過AfxBeginThread函數(shù)獲得。把start里面的聲明去掉。
然后添加一個 pause 按鈕向其響應函數(shù)里面添加代碼 mythread->SuspendThread();   再添加一個 resume按鈕,向其響應函數(shù)里面添加 mythread->ResumeThread();
    再運行程序,我們start之后,按下pause可以看到CPU恢復正常,然后resume,CPU又漲上去了,到此證明一切操作正常。

具體 總結如下

AfxBeginThread創(chuàng)建線程

1.聲明線程函數(shù):

UINT StartDownloadThread(LPVOID pParam);    // 下載線程,
2.創(chuàng)建線程:

CWinThread* m_pThread;     // 線程對象指針
// 創(chuàng)建多線程
void CMyDownloadDlg::CreateThread(CDLoadThread* pDloadThread)
{
  // 創(chuàng)建響應線程,啟動線程函數(shù)
  m_pThread = AfxBeginThread(StartDownloadThread, (LPVOID)pDloadThread);

  if(NULL == m_pThread)
  {
    TRACE("創(chuàng)建新的線程出錯!\n");
    return;
  }

}

 3.定義線程函數(shù)  

UINT StartDownloadThread(LPVOID pParam)
{
  // 為每個線程(任務數(shù))創(chuàng)建一個套接字來完成下載
  CDLoadThread* pThis = (CDLoadThread*)pParam;
  LONG indexTask = 0;
  //indexTask = pThis->m_indexThread;
  LONG indextNum = pThis->httpDload.m_index;
  InterlockedIncrement(&pThis->httpDload.m_index); // 互斥方法訪問共享資源,防止沖突

  int ret = pThis->httpDload.CreateThreadFunc(indexTask, indextNum);
  
  //TRACE("線程%d已成功完成!%d\n", index, ret);

  return 0;
}

以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。

相關文章

  • C++使用opencv讀取圖片的操作代碼(圖像處理)

    C++使用opencv讀取圖片的操作代碼(圖像處理)

    這篇文章主要介紹了C++使用opencv讀取圖片,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • C語言大廠面試技巧及strcpy()函數(shù)示例詳解

    C語言大廠面試技巧及strcpy()函數(shù)示例詳解

    這篇文章主要為大家介紹了C語言面試技巧,以strcpy()函數(shù)為示例進行分析詳解,有需要沖刺大廠的朋友們可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • C++入門語法之函數(shù)重載詳解

    C++入門語法之函數(shù)重載詳解

    這篇文章主要為大家詳細介紹了C++入門語法之函數(shù)重載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C++ 關于MFC List Control 控件的總結

    C++ 關于MFC List Control 控件的總結

    這篇文章主要介紹了C++ 關于MFC List Control 控件的總結的相關資料,十分的詳細,有需要的朋友可以參考下
    2015-06-06
  • 用C語言winform編寫滲透測試工具實現(xiàn)SQL注入功能

    用C語言winform編寫滲透測試工具實現(xiàn)SQL注入功能

    本篇文章主要介紹使用C#winform編寫滲透測試工具,實現(xiàn)SQL注入的功能。使用python編寫SQL注入腳本,基于get顯錯注入的方式進行數(shù)據(jù)庫的識別、獲取表名、獲取字段名,最終獲取用戶名和密碼;使用C#winform編寫windows客戶端軟件調(diào)用.py腳本,實現(xiàn)用戶名和密碼的獲取
    2021-08-08
  • 如何在 C++ 中實現(xiàn)一個單例類模板

    如何在 C++ 中實現(xiàn)一個單例類模板

    這篇文章主要介紹了如何在 C++ 中實現(xiàn)一個單例類模板,幫助大家更好的理解和學習c++編程,感興趣的朋友可以了解下
    2020-10-10
  • C/C++合并兩個升序鏈表的方式

    C/C++合并兩個升序鏈表的方式

    這篇文章主要介紹了C/C++合并兩個升序鏈表的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++提取文件名與提取XML文件的方法詳解

    C++提取文件名與提取XML文件的方法詳解

    這篇文章主要為大家詳細介紹了C++提取文件名與提取XML文件的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助<BR>
    2022-03-03
  • C語言代碼實現(xiàn)簡單2048游戲

    C語言代碼實現(xiàn)簡單2048游戲

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)2048游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題

    解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題

    今天小編就為大家分享一篇解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07

最新評論