C++ AfxBeginThread的介紹/基本用法_C 語言

來源:互聯網
上載者:User

AfxBeginThread 

   使用介面執行緒和工作者線程都是由AfxBeginThread建立的。現在,考察該函數:MFC提供了兩個重載版的AfxBeginThread,一個用於使用介面執行緒,另一個用於工作者線程,分別有如下的原型和過程:

使用介面執行緒的AfxBeginThread
使用介面執行緒的AfxBeginThread的原型如下:

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

其中:
參數1是從CWinThread派生的RUNTIME_CLASS類;
參數2指定線程優先順序,如果為0,則與建立該線程的線程相同;
參數3指定線程的堆棧大小,如果為0,則與建立該線程的線程相同;
參數4是一個建立標識,如果是CREATE_SUSPENDED,則在懸掛狀態建立線程,線上程建立後線程掛起,否則線程在建立後開始線程的執行。
參數5表示線程的安全屬性,NT下有用。

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

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

其中:
參數1  線程的入口函數,聲明一定要如下: UINT MyThreadFunction( LPVOID pParam );
參數2 傳遞入線程的參數,注意它的類型為:LPVOID,所以我們可以傳遞一個結構體入線程.
參數3、4、5分別指定線程的優先順序、堆棧大小、建立標識、安全屬性,含義同使用介面執行緒。

附錄A:

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

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

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

當然你可以定義自己的認為合適的值來代表線程成功執行.線上程內調用AfxEndThread將會直接結束線程,此時線程的一切資源都會被回收.

     2 : 如果你想讓別一個線程B來結束線程A,那麼,你就需要在這兩個線程中傳遞資訊.不管是工作者線程還是介面線程,如果你想線上程結束後得到它的確結果,那麼你可以調用     ::GetExitCodeThread函數

還是老師的那個項目,以前由於計算量太大,導致程式經常出現假死的現象,因為程式只有一個線程,該線程主要用於處理計算上了,而對於訊息佇列的響應被忽略了。因此解決的辦法就是用兩個線程,一個線程用於計算,一個線程用於處理訊息。

      到網上找了一些資料,發現在MFC中把線程分為兩類,一類為介面線程,一類為背景工作執行緒。兩者的區別在於前都能夠處理訊息響應,而後者則不能。對於該項目來說,只要把計算的過程放到一個背景工作執行緒裡來進行就可以了。

    現在先試一下,我建立了一個對話方塊,上面添加兩個按鈕,一個是start 一個是dialog。前者用於開始計算,而後者則彈出一個訊息框。然後向該對話方塊裡面添加一個死迴圈的函數

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

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

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

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

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

     其實上面的那個AfxBeginThread,除前面兩個參數外,後面的都是預設參數,可以省略。而必須有的這兩個參數,一個是線程函數的指標,一個是傳遞給這個函數的參數。實際中我們經常這樣用 AfxBeginThread(ThreadProc,this);//把this傳過去,就可以調用類的成員了. 這樣線程函數就可以使用和操作類的成員了。千萬要注意線程函數是靜態類函數成員。

    線程是建立了,但是如果中途要暫停該怎麼做呢?

    我們在建立線程的時候獲得了一個CWinThread的指標,這是一個指向線程對象的指標,CWinThread類裡面就有暫停與恢複的函數,下面我就示範一下。

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

具體 總結如下

AfxBeginThread建立線程

1.聲明線程函數:

UINT StartDownloadThread(LPVOID pParam);    // 下載線程,
2.建立線程:

CWinThread* m_pThread;     // 線程對象指標// 建立多線程void CMyDownloadDlg::CreateThread(CDLoadThread* pDloadThread){  // 建立響應線程,啟動線程函數  m_pThread = AfxBeginThread(StartDownloadThread, (LPVOID)pDloadThread);  if(NULL == m_pThread)  {    TRACE("建立新的線程出錯!\n");    return;  }}

 3.定義線程函數  

UINT StartDownloadThread(LPVOID pParam){  // 為每個線程(任務數)建立一個通訊端來完成下載  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;}

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.