請問Thread的用法 |
答題得分者是:lu
|
dan500
一般會員 發表:4 回覆:3 積分:1 註冊:2007-10-28 發送簡訊給我 |
從來沒寫過Thread的程式
只有以前學OS的時候大概知道其概念 假設現在要寫一個利用Thread完成的影像處理工作 像是...利用兩個Thread將一張影像做Sobel edge 首先...我建一個thread叫MyThread好了 將Sobel的Code寫在Execute()裡 接著在主程式上new兩個MyThread 便都去Resume 但我也一個疑問 像這種多個thread去執行同一支程式 當有一個thread進去做時...其他thread不就被擋在外面? (我有在程式內用Critical section...以免有問題) 那這樣多個Thread不就沒有意義? 不好意思...不知道有沒有人看的懂我的意思 我覺得這一定是個很白痴的問題 但希望有人可以幫我解答一下 今天下午去找相關的書...也沒有解答 不知道有沒有人可以推薦關於這方面的書? 我一值不懂thread的實作...雖然知道他的意義(多工) 編輯記錄
dan500 重新編輯於 2007-11-11 20:39:33, 註解 無‧
|
HomeSound
中階會員 發表:44 回覆:178 積分:94 註冊:2002-08-31 發送簡訊給我 |
於BCB IDE還境File->New...->選Thread Object以下是內容:
void __fastcall TReadS::Execute() { FreeOnTerminate = true;//執行緒的自動被釋放 while(!Terminated) //若執行緒已終止則跳出 { 最好有Delay幾秒的函數 Synchronize(要執行的自定函數); Application->ProcessMessages(); if(Terminated) break; //若多緒已終止則跳出 }//多緒環境中不可以直接呼叫VCL元件函式,需要Synchronize(SCheckBox)包住,以呼叫SCheckBox函數 //以確保在同一時間內只執行一個執行緒.建議單顆CPU不要開超過16個執行緒 } //如果於Execute函數中用break return時,則會中斷此執行緒 可用 goto END1; END1:; void __fastcall TReadS::自定函數(void) {程式內容........... } 於主Form如ReadSThread = new TReadS(false); //建立執行緒 若是(true)則是先暫停 ReadSThread->Terminate();//結束多執行緒 delete ReadSThread;//不需要作解構處理只要上述的Terminate()即可. 在主要的Form裡的某些程序中使用暫停或重新開始此執行緒 ReadSThread->Resume(); //重新開始執行緒(執行Execute()函數) ReadSThread->Suspend(); //暫時取消執行緒 ReadSThread->Priority=tpLower; //設執行緒於CPU中為低優先權 以上應該正確還有很多要注意的,請各位前輩指正喲!
------
--==多看.多學.多聽==-- |
lu
高階會員 發表:11 回覆:189 積分:195 註冊:2003-11-19 發送簡訊給我 |
想寫 MultiThread 的程式的朋友們,建議先去找本 MultiThread 的書來看,至少你要搞懂什麼叫 Thread, Process ,deadlock
以及 Event , Mutex ,Critical Section以及Semaphores 的用法,以及什麼是 ThreadSafe 搞懂以上的東西後,再去看看 Borland 的 TThread 的用法,尤其是 Synchronize 是如何運作低 然後再開始寫程式 以下程式碼,有一個錯誤,就是在 Execute(),呼叫 Application->ProcessMessages(); 這會導致,程式處於危險的狀態,所謂的危險的狀態,就是程式在RUN會ERROR出現,但是你不知道什麼時候會出現,以及哪裡會出現錯誤 若以上這句話看不懂在說什麼,請先去看書或MSDN,因為這一部份要說明清楚,大概快可以寫半本書了 另外站上有許多THREAD方面的討論,請先搜尋一下,爬爬文 ===================引 用 HomeSound 文 章=================== 於BCB IDE還境File->New...->選Thread Object以下是內容: void __fastcall TReadS::Execute() { FreeOnTerminate = true;//執行緒的自動被釋放 while(!Terminated) //若執行緒已終止則跳出 { 最好有Delay幾秒的函數 Synchronize(要執行的自定函數); Application->ProcessMessages(); if(Terminated) break; //若多緒已終止則跳出 }//多緒環境中不可以直接呼叫VCL元件函式,需要Synchronize(SCheckBox)包住,以呼叫SCheckBox函數 //以確保在同一時間內只執行一個執行緒.建議單顆CPU不要開超過16個執行緒 } //如果於Execute函數中用break return時,則會中斷此執行緒 可用 goto END1; END1:; void __fastcall TReadS::自定函數(void) {程式內容........... } 於主Form如ReadSThread = new TReadS(false); //建立執行緒 若是(true)則是先暫停 ReadSThread->Terminate();//結束多執行緒 delete ReadSThread;//不需要作解構處理只要上述的Terminate()即可. 在主要的Form裡的某些程序中使用暫停或重新開始此執行緒 ReadSThread->Resume(); //重新開始執行緒(執行Execute()函數) ReadSThread->Suspend(); //暫時取消執行緒 ReadSThread->Priority=tpLower; //設執行緒於CPU中為低優先權 以上應該正確還有很多要注意的,請各位前輩指正喲! |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
如同 lu 所說,HomeSound 在 Execute() 內使用 Application->ProcessMessages();
是很危險的喔,我以前也是出了這樣的錯誤,但在之前就有問過關於 Thread 的相關 問題,請搜尋 thread dllee,您會發現許多有用的文章(許多 lu 的好文章不可錯過)。 另外,做Sobel edge 為什麼要開兩個 Thread 呢? 又如果兩個 Thread 用的資源相同,又幾乎所有的 Code 都用Critical section 包起來, 那就用一個 Thread 就好了。 要使 Thread 的作用提高,在 Thread 內不要使用 Synchronize,只作資料/數值計算, 在主執行緒再去讀運算結果作顯示,這樣,才有多執行緒的效果。否則,只是執行緒 看起來多,但運作起來與單執行緒是一樣的,若沒寫好,更容易發生問題。 ■ VMASK - ViewMove Automation Software Kernel ■ VMIO-Server/SECS/GEM ■ dllee's blog ■ dllee's StatPlus ■
------
http://www.ViewMove.com |
cwchiu
一般會員 發表:1 回覆:4 積分:1 註冊:2007-09-05 發送簡訊給我 |
抱歉,請教一下,當 ActiveX 裡面使用 TThread
當我撰寫 LoadZipDocThread* thread = new LoadZipDocThread(m_parent, url, OnComplete); thread->OnTerminate = OnThreadTerminate; 我有兩個問題請教 1. OnThreadTerminate 為什麼不會觸發,當 TThread 的 Execute 執行結束時,不是應該會結束 TThread 並觸發 OnTerminate 事件嗎? 2. 我在 TThread 中使用 ActiveX 的 Fire_XXXX 可是前端卻沒有辦法收到 這個 XXXX 事件,我用 Debug 方式確定他有調用 Fire_XXXX .....WHY? 煩請指點一下 謝謝 |
lu
高階會員 發表:11 回覆:189 積分:195 註冊:2003-11-19 發送簡訊給我 |
1. 基本上只要有寫 OnTerminate 就一定會觸發,若沒有觸發,比較有可能的原因為就是你在 NEW 一個TThread 時設定為立即執行(請參閱 TThread 的相關說明),導致Thread 已經執行完了,但是你還沒把 OnTerminate 設定上去
2. 你所謂的前端指的是什麼?若是一般的C/C 的程式,要收到那個事件我記得還要花點功夫.....(題外話,這就是COM難用的地方,也是為啥M$要推COM PLUS),若要寫ACTIVE X控制項建議用 VB6 來測試,因為VB的環境比較特殊(M$為了遷就VB,把COM的介面搞得異常複雜),VB可以正常WORK,那大致上都OK了 ===================引 用 cwchiu 文 章=================== 抱歉,請教一下,當 ActiveX 裡面使用 TThread 當我撰寫 LoadZipDocThread* thread = new LoadZipDocThread(m_parent, url, OnComplete); thread->OnTerminate = OnThreadTerminate; 我有兩個問題請教 1. OnThreadTerminate 為什麼不會觸發,當 TThread 的 Execute 執行結束時,不是應該會結束 TThread 並觸發 OnTerminate 事件嗎? 2. 我在 TThread 中使用 ActiveX 的 Fire_XXXX 可是前端卻沒有辦法收到 這個 XXXX 事件,我用 Debug 方式確定他有調用 Fire_XXXX .....WHY? 煩請指點一下 謝謝 |
cwchiu
一般會員 發表:1 回覆:4 積分:1 註冊:2007-09-05 發送簡訊給我 |
非常感謝 lu 的回覆,不然真的找不到人可以請教 T_T
1. 我將程式在 new 時先設為 Suspended,等參數設定完成後再 Resume 依然如此~ 2. 抱歉這個我沒有說清楚,我的前端是用 IE 瀏覽器,VB6 我測試可以正常運作,但放到網頁上 Event 就沒有辦法收到。 下面是我的測試程式片段 [code cpp] class LoadZipDocThread : public TThread{ protected: void __fastcall Execute(); public: __fastcall LoadZipDocThread(TActiveFormXImpl* parent) : TThread(true), m_parent(parent){ FreeOnTerminate=true; } private: TActiveFormXImpl* m_parent; }; STDMETHODIMP TActiveFormXImpl::doIt() { try { LoadZipDocThread* thread = new LoadZipDocThread(this); thread->OnTerminate = OnMyComplete; thread->Resume(); } catch(Exception &e) { return Error(e.Message.c_str(), IID_IActiveFormX); } return S_OK; }; void __fastcall LoadZipDocThread::Execute(){ m_parent->Fire_OnXXXX(); } void __fastcall TActiveFormXImpl::OnMyComplete(TObject* sender){ ShowMessage("OnMyComplete"); } [/code] 完整程式如下: http://sisimi.pchome.googlepages.com/Ax.rar 是不是我哪弄錯了 ... ===================引 用 lu 文 章=================== 1. 基本上只要有寫 OnTerminate 就一定會觸發,若沒有觸發,比較有可能的原因為就是你在 NEW 一個TThread 時設定為立即執行(請參閱 TThread 的相關說明),導致Thread 已經執行完了,但是你還沒把 OnTerminate 設定上去 2. 你所謂的前端指的是什麼?若是一般的C/C 的程式,要收到那個事件我記得還要花點功夫.....(題外話,這就是COM難用的地方,也是為啥M$要推COM PLUS),若要寫ACTIVE X控制項建議用 VB6 來測試,因為VB的環境比較特殊(M$為了遷就VB,把COM的介面搞得異常複雜),VB可以正常WORK,那大致上都OK了 |
lu
高階會員 發表:11 回覆:189 積分:195 註冊:2003-11-19 發送簡訊給我 |
剛剛瞄了一下你的程式碼,問一下你有手動修改過 ActiveFormImpl1.h 嗎?
看起來怪怪低,為啥 doit() 會在兩個地方宣告,可能是BCB版本不同所導致,我用的是BCB5..... 你可以善用 Debug 的功能,點選 [Run] -> [Parametes] 可以設定用其他程式執行這個 Active X,詳細用法請參閱help 再提醒你一次Active X 在VB和在IE裡面有些細微的小差異,你要注意,在VB可以,不代表在IE裡面可以 還有在ACTIVE X裡面用THREAD,要小心喔,特別是你還在 Execute 裡面呼叫 Fire_OnXXXX 『危險動作』,請確定你真的知道你在作什麼 另外~~提一下,這是我第一次幫別人看CODE.....雖然只有短短的20秒 題外話 站上有許多大大功力深厚,不過若有人希望他棉可以看CODE,幫忙DEBUG,特別是所有的CODE..... 我建議屬了那條心吧 原因如下 1. 看別人寫的CODE,比自己重新寫一次還累,特別是那些不照規矩替變數取名稱的CODE,天曉得 cc,tt,aa,bb 代表啥意思 2. 幫別人DEBUG,那東西還是我的,只有自己跳下來抓BUG,東西才會變你的 3. 寫程式沒啥了不起,我學生時代就寫的嚇嚇叫了,會DEBUG才是功力,因為DEBUG要有方法,大多數的時候,你還要擬定測試計畫,才抓得到BUG 特別是原因2、3,所以站上的大大不願意,幫人DEBUG,因為這樣成長的永遠是別人 有感而發,不要介意 ===================引 用 cwchiu 文 章=================== 非常感謝 lu 的回覆,不然真的找不到人可以請教 T_T 1. 我將程式在 new 時先設為 Suspended,等參數設定完成後再 Resume 依然如此~ 2. 抱歉這個我沒有說清楚,我的前端是用 IE 瀏覽器,VB6 我測試可以正常運作,但放到網頁上 Event 就沒有辦法收到。 下面是我的測試程式片段 完整程式如下: http://sisimi.pchome.googlepages.com/Ax.rar 是不是我哪弄錯了 ... |
cwchiu
一般會員 發表:1 回覆:4 積分:1 註冊:2007-09-05 發送簡訊給我 |
1. 我用的是 BCB6, doIt 可能我寫測試程式的時候沒有注意,應該只有一份
2. BCB 對 ActiveX Debug 方式我已經用過,所以,我很確定他有執行到 Fire_OnXXXX.... 3. 我希望透過 ActiveX 執行某個冗長的運算後,透過事件通知使用元件的應用程式,所以,我才會在 TThread 中丟出事件,我原本想要放在 OnTerminate ,可是他沒有辦法運作,所以,我就先放在 Execute 中。不過,為什麼 Execute 不適合丟出事件呢? 4. 附上測試程式是比較容易讓大家知道我的程式在寫什麼,不是想要有人幫我 DEBUG,也不需要給我完整程式碼,我只是想了解問題的原因或是 BUG,為什麼 ActiveX 內不能正常使用 TThread ( OnTerminate 不能正常觸發)?TThread 為什麼沒有辦法正常丟出事件 (Fire_OnXXXX 後前端收不到事件)?或是有其他方式可以滿足我的需要呢? 感謝大家的回覆 ~~~~~~~ ===================引 用 lu 文 章=================== 剛剛瞄了一下你的程式碼,問一下你有手動修改過 ActiveFormImpl1.h 嗎? 看起來怪怪低,為啥 doit() 會在兩個地方宣告,可能是BCB版本不同所導致,我用的是BCB5..... 你可以善用 Debug 的功能,點選 [Run] -> [Parametes] 可以設定用其他程式執行這個 Active X,詳細用法請參閱help 再提醒你一次Active X 在VB和在IE裡面有些細微的小差異,你要注意,在VB可以,不代表在IE裡面可以 還有在ACTIVE X裡面用THREAD,要小心喔,特別是你還在 Execute 裡面呼叫 Fire_OnXXXX 『危險動作』,請確定你真的知道你在作什麼 另外~~提一下,這是我第一次幫別人看CODE.....雖然只有短短的20秒 題外話 站上有許多大大功力深厚,不過若有人希望他棉可以看CODE,幫忙DEBUG,特別是所有的CODE..... 我建議屬了那條心吧 原因如下 1. 看別人寫的CODE,比自己重新寫一次還累,特別是那些不照規矩替變數取名稱的CODE,天曉得 cc,tt,aa,bb 代表啥意思 2. 幫別人DEBUG,那東西還是我的,只有自己跳下來抓BUG,東西才會變你的 3. 寫程式沒啥了不起,我學生時代就寫的嚇嚇叫了,會DEBUG才是功力,因為DEBUG要有方法,大多數的時候,你還要擬定測試計畫,才抓得到BUG 特別是原因2、3,所以站上的大大不願意,幫人DEBUG,因為這樣成長的永遠是別人 有感而發,不要介意 ===================引 用 cwchiu 文 章=================== 非常感謝 lu 的回覆,不然真的找不到人可以請教 T_T 1. 我將程式在 new 時先設為 Suspended,等參數設定完成後再 Resume 依然如此~ 2. 抱歉這個我沒有說清楚,我的前端是用 IE 瀏覽器,VB6 我測試可以正常運作,但放到網頁上 Event 就沒有辦法收到。 下面是我的測試程式片段 完整程式如下: http://sisimi.pchome.googlepages.com/Ax.rar 是不是我哪弄錯了 ... |
lu
高階會員 發表:11 回覆:189 積分:195 註冊:2003-11-19 發送簡訊給我 |
把某些事丟給 Thread 作運算,在計算完成後通知使用者計算完成,這是THREAD的基本用法沒錯,至於為什麼有2個 doit 這一部份我懷疑是BCB的錯誤,因為我個人也常常遇到,建議你重新開另外一個PROJECT重新作,然後先把ACTIVE X所需的介面全部一次設定完成,然後再寫程式碼,你的問題我想大概就可以解決了
至於在 Execute 不適合丟出事件,原因為你是在另外一個THREAD中丟出事件,不是在MAIN THREAD之中,這會很容易造成使用你這個ACTIVE X的程式(如:IE、VB等等)的錯誤,這一部份不容易講的清楚,請參閱MSDN有關THREAD部分的相關說明 你問不用OnTerminate 要用什麼方式來通知THREAD執行完成,方法很多,最簡單的方式就是用 SendMessage 或 PostMessage,這一部份你可以研究一下,一定用得到,舉例來說,你在那個落落長的運算中,需不需要通知使用者或程式設計者,運算的進度?很多時候是需要低,這時你要用什麼方法? 另外,使用BCB內的 TThread 會比較耗費資源喔,因為 TThread 會產生一個 Window Handle 來處理其他相關事宜......這一部份請參閱TTHREAD的SOURCE CODE ===================引 用 cwchiu 文 章=================== 1. 我用的是 BCB6, doIt 可能我寫測試程式的時候沒有注意,應該只有一份 2. BCB 對 ActiveX Debug 方式我已經用過,所以,我很確定他有執行到 Fire_OnXXXX.... 3. 我希望透過 ActiveX 執行某個冗長的運算後,透過事件通知使用元件的應用程式,所以,我才會在 TThread 中丟出事件,我原本想要放在 OnTerminate ,可是他沒有辦法運作,所以,我就先放在 Execute 中。不過,為什麼 Execute 不適合丟出事件呢? 4. 附上測試程式是比較容易讓大家知道我的程式在寫什麼,不是想要有人幫我 DEBUG,也不需要給我完整程式碼,我只是想了解問題的原因或是 BUG,為什麼 ActiveX 內不能正常使用 TThread ( OnTerminate 不能正常觸發)?TThread 為什麼沒有辦法正常丟出事件 (Fire_OnXXXX 後前端收不到事件)?或是有其他方式可以滿足我的需要呢? 感謝大家的回覆 ~~~~~~~ |
cwchiu
一般會員 發表:1 回覆:4 積分:1 註冊:2007-09-05 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |