我們都會發現,如過給主視窗過多的任務,或者讓主視窗過多地sleep,那麼主視窗很難響應使用者的任何操作,
甚至在此種情況下想要移動一下主視窗都會造成視窗標題欄顯示「沒有響應」,如此一來,大多使用者都會啟動任
務管理器來結束這個假死的視窗。
如何避免這種情況呢?
一種辦法就是使用多執行緒,也就是把那些耗時耗力的工作交給主視窗的子執行緒,如此以來,假死的就不是主視窗而是使用者看不見的子執行緒了,而此時視窗仍然可以正常地響應使用者的一些操作。
具體方法是:
在即將啟動子執行緒的視窗類的類體外(注意一定是類體外!)定義出子執行緒要執行的函式,該函式的格式必須是(注意必須!):
uint functionname(lpvoid pparam)
// ***處寫返回值,一般說來這個返回值沒什麼用處,只是為了跳出函式
函式定義完了,於是該啟動乙個子執行緒來執行這個函式了,啟動的方法是:
cwinthread* afxbeginthread( afx_threadproc pfnthreadproc, lpvoid pparam, int npriority = thread_priority_normal, uint nstacksize = 0, dword dwcreateflags = 0, lpsecurity_attributes lpsecurityattrs = null );
千萬不要被這個函式複雜的引數所下到,因為通常情況只用到前兩個引數,後幾個預設即可,比如我們可以這樣寫:
afxbeginthread(functionname,getsafehwnd());//別問我第二個引數為什麼是這樣,通常都這樣寫,它用於和啟動子執行緒的視窗通訊。
到這裡,乙個最簡單的「多執行緒」就算出爐了,在程式執行到afxbeginthread(functionname,getsafehwnd());時,子執行緒就會被啟動來完成一定的操作。
實際上的多執行緒並不這樣簡單,子執行緒並非總應在afxbeginthread(functionname,getsafehwnd());之後被啟動,而且也不應總執行一遍函式體就結束。實際上我們還經常用cevent類物件來觸發乙個已經啟動的子執行緒開始執行,相應地,子執行緒也必須等待收到指定的cevent物件時才真正執行。乙個比較完善的子執行緒:
uint functionname(lpvoid pparam)
這個例子中::waitforsingleobject(refresh,infinite);一句的refreshe是乙個cevent類物件,infinite指定無限時地等待refresh的到來,只有收到refresh後才繼續往下執行,refresg的傳送方法是:refresh.setevent;::postmessage((hwnd)pparam,wm_refresh,0,0);一句就是與pparam視窗(通常是啟動它的視窗)通訊,wm_refresh是自定義訊息,當然,pparam視窗中還必須有能接受並相應這個訊息的函式例如可以是:afx_msg lresult onrefresh(wparam wparam,lparam lparam);
為什麼一定要用這種方法來和主視窗通訊呢?很簡單,因為子執行緒所執行的函式被定義在了類體外。
最後一點,當主視窗被關閉後,子執行緒就自動終止了,如果要在執行期間結束,就呼叫void afxendthread( uint nexitcode );這個函式很簡單,看一下msdn即可,在此不做贅述。
VC MFC 多執行緒及執行緒同步
自動事件 cevent類的建構函式,第二個引數為false,是自動事件,自動事件在呼叫setevent函式被使用後能夠自動恢復為無訊號狀態。預設情況下,是自動事件。1 宣告事件為全域性物件。包含使用執行緒同步物件所需要的標頭檔案 include afxmt.h cevent eventobj 構造乙...
(40)多執行緒 實現多執行緒方法
建立執行緒用法 1.繼承thread,重寫run 方法,建立子類物件 a a new a 執行緒開始執行 a.start 2.實現runnable介面,實現run 方法,建立實現類物件 a a new a 建立 類物件 thread t new thread a 執行緒開始執行 t.start 上面...
執行緒基礎 實現多執行緒
public class thread01 extends thread public static void main string args public class thread02 implements runnable public static void main string args...