久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1081|回復: 0
打印 上一主題 下一主題
收起左側

AfxBeginThread

[復制鏈接]
跳轉到指定樓層
樓主
ID:310593 發表于 2018-4-18 08:49 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
用戶界面線程和工作者線程都是由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又漲上去了,到此證明一切操作正常

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: www.久久 | 韩日一区二区三区 | 日韩精品成人一区二区三区视频 | 国产一区二区三区在线视频 | 精品粉嫩aⅴ一区二区三区四区 | 欧美日本韩国一区二区三区 | 成人免费视频 | 国产中文| 在线一区二区三区 | 人人做人人澡人人爽欧美 | 国产视频导航 | 一区二区久久 | 拍真实国产伦偷精品 | 国产精品视屏 | 欧美九九九 | 欧美一区二区三区在线看 | 成人性生交大片免费看r链接 | 精品综合在线 | 欧美成人精品一区二区三区 | 精品欧美激情在线观看 | 国产一区二区在线免费播放 | 中文字幕一区二区三区乱码在线 | 蜜桃av一区二区三区 | 久久亚洲综合 | 国产一区二区自拍 | 男女下面一进一出网站 | 日韩综合在线播放 | 久久精品97 | 国产成人久久精品一区二区三区 | 91久久久www播放日本观看 | 久久亚洲一区 | 国产精品一区二 | 免费观看的av毛片的网站 | 国产一区二区三区高清 | 性欧美精品一区二区三区在线播放 | 久久99这里只有精品 | 99热在线观看精品 | 色欧美综合| 99久久婷婷国产亚洲终合精品 | 波多野结衣在线观看一区二区三区 | 99热首页|