一般而言 ,
應用程式中的乙個次要執行緒總是為主執行緒執行特定的任務,這樣
,主線程和次要執行緒間必定有乙個資訊傳遞的渠道,
也就是主線程和次要執行緒間要進行通訊。這種執行緒間
的通訊不但是難以避免的,而且在多執行緒程式設計中也是複雜和頻繁的,下面將進行說明。
使用全域性變數進行通訊
由於屬於同乙個程序的各個執行緒共享作業系統分配該程序的資源,故解決執行緒間通訊最簡單的一種方法是使用全域性變數。對於標準型別的全域性變數,我們建議使用 volatile
修飾符, 它告訴編譯器無需對該變數作任何的優化,即無需將它放到乙個暫存器中,並且該值可被外部改變。如果執行緒間所需傳遞的資訊較複雜,我們可以定義乙個結構,通過傳遞指向該結構的指標進行傳遞資訊。
使用自定義訊息
我們可以在乙個執行緒的執行函式中向另乙個執行緒傳送自定義的訊息來達到通訊的目的。一 個執行緒向另外乙個執行緒傳送訊息是通過作業系統實現的。利用 windows
作業系統的訊息驅動機制,當乙個執行緒發出一條訊息時,作業系統首先接收到該訊息,然後把該訊息**給目標執行緒,接收訊息的執行緒必須已經建立了訊息迴圈。
例程:multithreadcalc
該例程演示了如何使用自定義訊息進行執行緒間通訊。首先,主線程向 ccalculatethread執行緒傳送訊息 wm_calculate,ccalculatethread 執行緒收到訊息後進行計算,再向主線程傳送 wm_display 訊息,主線程收到該訊息後顯示計算結果。
建立乙個基於對話方塊的工程 multithread7,在對話方塊 idd_multithreadcalc_dialog中加入三個單選按鈕 idc_radio1,idc_radio2,idc_radio3,標題分別為 1+2+3+4+......+10,1+2+3+4+......+50,1+2+3+4+......+100。加入按鈕 idc_btnadd,標題為「求和」。加入標籤框idc_status,屬性選中「邊框」;
在 multithreadcalcdlg.h 中定義如下變數:
protected:
int naddend;
代表加數的大小。
分別雙擊三個單選按鈕,新增訊息響應函式:
void cmultithreadcalcdlg::onradio1()
void cmultithreadcalcdlg::onradio2()
void cmultithreadcalcdlg::onradio3()
並在 oninitdialog 函式中完成相應的初始化工作:
((cbutton*)getdlgitem(idc_radio1))->setcheck(true);
naddend =10;
在 multithreadcalcdlg.h **如下:
#include #include "ccalculatethread.h"
// cmultithreadcalcdlg dialog
#define wm_display wm_user+2 // 自定義訊息
class cmultithreadcalcdlg : public cdialog
; // note: the classwizard will add data members here
//}}afx_data
// classwizard generated virtual function overrides
//}afx_virtual
// implementation
protected:
int naddend;
hicon m_hicon;
// generated message map functions
//}afx_msg
declare_message_map()
};
在
multithreadcalcdlg.cpp 中的begin_message_map中加wm_display訊息對映及響應:
on_message(wm_display, ondisplay)
lresult cmultithreadcalcdlg::ondisplay(wparam wparam, lparam lparam)
以上**使得主線程類
multithreadcalcdlg可以處理 wm_display 訊息,即在 idc_stat us標籤框中顯示計算結果。雙擊按鈕 idc_btn_add,新增訊息響應函式:
void cmultithreadcalcdlg::onbtnadd()
onbtnadd()函式的作用是建立c
calculatethread
執行緒,延時給該執行緒傳送
wm_calculate
訊息。右 擊 工 程 並 選 中 「 new class
… 」 為 工 程 添 加 基 類 為
cwinthread
派 生 線 程 類ccal ulatethread。其標頭檔案如下:
#define wm_calculate wm_user+1
class ccalculatethread : public cwinthread
}afx_virtual
// implementation
protected:
virtual ~ccalculatethread();
afx_msg long oncalculate(wparam wparam, lparam lparam);
// generated message map functions
//}afx_msg
declare_message_map()
};
在檔案 ccalculatethread.cpp 中新增:
long ccalculatethread::oncalculate(wparam wparam, lparam lparam)
sleep(500);
::postmessage((hwnd)(getmainwnd()->getsafehwnd()),wm_display,ntmpt,null);
return 0;
}begin_message_map(ccalculatethread, cwinthread)
//}afx_msg_map
on_thread_message(wm_calculate, oncalculate)
end_message_map()
以上**為 ccalculatethread 類新增了 wm_calculate 訊息,訊息的響應函式是 oncalculate,其功能是根據引數 wparam 的值,進行累加,累加結果在臨時變數 ntmpt中,延時 0.5 秒,向主線程傳送 wm_display 訊息進行顯示,ntmpt 作為引數傳遞。
mfc多執行緒間訊息通訊工程案例
多執行緒 執行緒間通訊
wait 方法的作用是使當前執行的執行緒進入等待,執行到 wait 一行進入等待 當執行緒被喚醒時從 wait 下一行開始執行。wait 方法需要在 synchronized 塊中呼叫,否則會報錯。wait 方法會釋放鎖,其它執行緒可以競爭獲得鎖 wait 方法有乙個帶時間引數的,當時間到了可以自動...
多執行緒 執行緒間通訊
學習思路 執行緒同步 鎖 wait notify join threadlocal 通過管道輸入 輸出流 字元流 位元組流 服務如果一直處於單執行緒訪問,那將毫無意義,多使用者訪問必然產生多執行緒,而多執行緒訪問必然離不開執行緒間通訊 多執行緒操作共享資源時勢必會產生執行緒安全的問題 也就是我們說的...
多執行緒3 執行緒間通訊
這兩種方法都要在同步 塊或同步方法中呼叫。都需要先獲得物件級別的鎖。只有兩個方法的物件鎖一致,即 物件監視器 一致,再能通過notify方法通知到執行wait方法的執行緒繼續執行。使用wait方法後,該執行緒會釋放物件鎖,並進入阻塞佇列等待被喚醒。notify方法喚醒wait方法後,該執行緒進入就緒...