關於多執行緒的一些細節 (轉)
關於多執行緒的一些細節
作者: coolnerd
執行緒的中,如果執行緒要向介面視窗報告狀態,有兩種操作方法,
一種是透過訊息的方法,由於訊息本身攜帶的訊息量有時不購用,往往訊息引數
只是一個指向某訊息的指標,而訊息物件往往需要在堆中new生成,
(因為往往執行緒不能等待訊息處理完畢就繼續,所以如果訊息物件是棧物件
往往訊息物件還未來及被處理,就又被執行緒修改.所以採用堆物件.)
介面接受到
訊息物件後delete之.但是這時介面退出後,如果執行緒仍然生成新的訊息物件,
則訊息物件得不到釋放,所以在這種情況下,介面接受到WM_CLOSE訊息將要釋放
之前,要等待執行緒完全退出之後再真正釋放.
執行緒向介面報告狀態的第二種方法是直接線上程的執行過程中同步地(等待,
直到完成稱為同步)執行介面顯示,這種機制下,要注意在介面顯示是需要檢視
介面視窗是否仍然存在(使用IsWindow(hWnd)實現).
這樣做似乎已經完美,但是是不完善的,因為假如有多個view小視窗,如多個
CSplitterWnd,只在一個CSplitterWnd的WM_CLOSE訊息的處理函式中進行防範,
其他的CSplitterWnd照常退出,仍然要出問題,所以要抓住根源:
使用選單退出或點選frmae視窗的x按鈕退出,接受到退出訊息的首先是frameWnd
所以需要在frameWnd的WM_CLOSE函式中進行執行緒的釋放.!
另外,往往執行緒在Document類的掌管之下,frame怎樣訪問document物件?
FrameWnd沒有直接提供獲取document的函式.Document,View,FrameWnd三者的
建立順序是:doc->Frmae->View,在View::InitUpdate()函式的執行時刻,
可以執行以下程式碼:
CMainFrame*frm=(CMainFrame*)(AfxGetApp()->m_pMainWnd);
frm->pDoc=GetDocument();
另外:注意需要捕捉WM_CLOSE,而非WM_DESTROY訊息,因為WM_CLOSE訊息
先於後者.
另外,考查以下程式碼:
void CThreadList::UpdateThread(int id,CString client,CString msg)
{
EnterCriticalSection(&CThreadList::csUpDateThread);
{
int ItemCount=m_ListCtrl.GetItemCount() ; //ListCtrl
最多65535條記錄
if(id>ItemCount)
{
for(int i=0;i
LV_ITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_IMAGE
/* |LVIF_STATE */;
lvi.iItem = ItemCount+i;
lvi.iSubItem = 0;
m_ListCtrl.InsertItem(&lvi);
//m_ListCtrl.SetItemCount(id);
}
}
m_ListCtrl.SetItemText(id-1,0,ito10a(id));
m_ListCtrl.SetItemText(id-1,1,client);
m_ListCtrl.SetItemText(id-1,2,msg);
}
LeaveCriticalSection(&CThreadList::csUpDateThread);
}
這就是執行緒用來的介面函式,該介面CThreadList
是個ListCtrl類,該成員函式的引數中,id,client,msg是介面顯示的內容
函式首先判斷id是否超出現在已經存在的個數,如果超出則增加一到多條記錄
這種動態調整記錄個數的機制比較誘人,但是如果這個函式是在這樣的情況下
被呼叫: frame視窗接受到了WM_CLOSE訊息,在處理訊息之前,首先消滅執行緒
而就在消滅執行緒的過程中,一個未來及消滅的執行緒呼叫了這個函式,該函式在
執行過程中需要執行GetItemCount()函式,跟蹤GetItemCount函式,發現它是
依靠執行SendMessage獲得ItemCount的(SendMessage函式是個不等到結果不
返回的函式),這時會發生的是當機,因為在處理WM_ClOSE訊息
未完成時,又被要求處理SendMessage函式,於是SendMessage函式和WM_CLOSE
訊息處理過程發生了互相等待的事故.
結論是不要線上程向介面報告狀態的過程中呼叫任何依靠訊息工作的函式.
經過考查,幾乎所有介面的函式如SetItemText都是依靠SendMessage
來工作的,所以會到問題的最初:"在多執行緒的程式中,如果執行緒要向介面視窗
報告狀態,有兩種操作方法"在這兩種方法中,第二種方法是行不通的.
※ 來源:·BBS 水木清華站 bbs.tsinghua.edu.cn·[FROM: 166.111.60.81]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988857/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 執行緒池中你不容錯過的一些細節執行緒
- Java 關於執行緒的一些使用Java執行緒
- java 多執行緒(關於Thread的講解)Java執行緒thread
- 關於Java多執行緒的執行緒同步和執行緒通訊的一些小問題(順便分享幾篇高質量的博文)Java執行緒
- 關於多執行緒的兩種實現方式執行緒
- 關於程式和執行緒 自我的一些總結執行緒
- Will it finally: 關於 try/catch 的一些細節
- 多執行緒的執行緒狀態及相關操作執行緒
- java多執行緒(超詳細!)Java執行緒
- python多執行緒中:如何關閉執行緒?Python執行緒
- 關於Java併發多執行緒的一點思考Java執行緒
- 有個關於多執行緒的識別問題執行緒
- 關於linux多執行緒fork的理解和學習Linux執行緒
- 對Java多執行緒的一些理解Java執行緒
- 多執行緒相關整理執行緒
- 關於C#多執行緒、易失域、鎖的分享C#執行緒
- 多執行緒和多執行緒同步執行緒
- 玩轉java多執行緒 之多執行緒基礎 執行緒狀態 及執行緒停止實戰Java執行緒
- 執行緒以及多執行緒,多程式的選擇執行緒
- 多執行緒--執行緒管理執行緒
- 執行緒與多執行緒執行緒
- 多執行緒【執行緒池】執行緒
- 多執行緒相關問題執行緒
- 關於redis單執行緒的分析Redis執行緒
- 關於執行緒設計的感受執行緒
- c#關於同步 /異常/多執行緒/事件 事例C#執行緒事件
- 關於c#多執行緒中的幾個訊號量C#執行緒
- 多執行緒(五)---執行緒的Yield方法執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- Java面試中,一些常見的有關多執行緒問題!Java面試執行緒
- 多執行緒併發的一些解決思路執行緒
- Java多執行緒-執行緒中止Java執行緒
- 多執行緒之初識執行緒執行緒
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- 多執行緒系列(1),多執行緒基礎執行緒
- 細說 Android 下的多執行緒,學會了多執行緒,你就學會了壓榨CPU!Android執行緒
- Java多執行緒相關知識Java執行緒
- 多執行緒之volative關鍵字執行緒