線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:8856
推到 Plurk!
推到 Facebook!

請問Thread的用法

答題得分者是:lu
dan500
一般會員


發表:4
回覆:3
積分:1
註冊:2007-10-28

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-11-11 17:37:29 IP:203.73.xxx.xxx 訂閱
從來沒寫過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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-11-12 03:35:03 IP:219.80.xxx.xxx 訂閱
於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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-11-12 17:39:46 IP:203.73.xxx.xxx 訂閱
想寫 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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-11-13 09:27:55 IP:220.134.xxx.xxx 訂閱
如同 lu 所說,HomeSound 在 Execute() 內使用 Application->ProcessMessages();
是很危險的喔,我以前也是出了這樣的錯誤,但在之前就有問過關於 Thread 的相關
問題,請搜尋 thread dllee,您會發現許多有用的文章(許多 lu 的好文章不可錯過)。

另外,做Sobel edge 為什麼要開兩個 Thread 呢?
又如果兩個 Thread 用的資源相同,又幾乎所有的 Code 都用Critical section 包起來,
那就用一個 Thread 就好了。
要使 Thread 的作用提高,在 Thread 內不要使用 Synchronize,只作資料/數值計算,
在主執行緒再去讀運算結果作顯示,這樣,才有多執行緒的效果。否則,只是執行緒
看起來多,但運作起來與單執行緒是一樣的,若沒寫好,更容易發生問題。

VMASK - ViewMove Automation Software KernelVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
------
http://www.ViewMove.com
cwchiu
一般會員


發表:1
回覆:4
積分:1
註冊:2007-09-05

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-11-13 11:43:21 IP:59.127.xxx.xxx 訂閱
抱歉,請教一下,當 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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-11-13 13:04:41 IP:203.73.xxx.xxx 訂閱
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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-11-13 14:47:46 IP:59.127.xxx.xxx 訂閱
非常感謝 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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-11-13 18:28:00 IP:203.73.xxx.xxx 訂閱
剛剛瞄了一下你的程式碼,問一下你有手動修改過 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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-11-13 19:09:07 IP:125.229.xxx.xxx 訂閱
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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2007-11-14 08:46:48 IP:203.73.xxx.xxx 訂閱
把某些事丟給 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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2007-11-14 17:53:22 IP:59.127.xxx.xxx 訂閱
感謝 lu,雖然我還是沒有找到錯誤真正的原因,不過目前用 Message 進行通知是可行的

這篇有討論到 ActiveX 使用 TThread 的一些問題,有需要的人可以參考
http://delphi.ktop.com.tw/board.php?cid=30&fid=68&tid=51222
系統時間:2024-05-05 16:51:52
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!