C++ AfxBeginThread的引見/根本用法。本站提示廣大學習愛好者:(C++ AfxBeginThread的引見/根本用法)文章只能為提供參考,不一定能成為您想要的結果。以下是C++ AfxBeginThread的引見/根本用法正文
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; }
以上所述就是本文的全體內容了,願望年夜家可以或許愛好。