全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3134
推到 Plurk!
推到 Facebook!

請問一個多執行緒的Terminate及Synchronize的問題!!

答題得分者是:RaynorPao
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-12-23 09:05:25 IP:210.241.xxx.xxx 未訂閱
各位大大好, 我有一個多執行緒的問題, 我把問題描述如下 1. 我有一個主程式, 在主程式的一開始我先設定Test *T3=new Test(true); Test是我Thread的名稱, T3事整體變數, 因此在主程式中我都可以使用T3 2. 我新增了一個Thread Object給Test, 裡面的程式很簡單, 只有 Void ShowLiteral() { Form1->Label10->Caption = "Test Thread running"; } __fastcall Test::Test(bool CreateSuspended) : TThread(CreateSuspended) { FreeOnTerminate = true; Priority = tpNormal; } void __fastcall Test::Execute() { //---- Place thread code here ---- while(!Terminated) { Synchronize(ShowLiteral()); } Form1->Label10->Caption = "Terminate Test Thread!!"; } 問題: 1. 可是上面的程式會發生一個問題, 當我Compiler時, 程式都會告知我 Cannot convert 'void(__fastcall*)()'to'void(__fastcall*(_closure)())() 2.我在主程式中加入了兩個按鈕,內容分別只有Test(false)及T3->Terminate() 若我不使用Synchronize則可以Compiler, 但執行兩個按鈕之後都攔截不到 Terminated, 而且run多次之後會當機!! 麻煩各位大大多多指教, 指正我程式中的錯誤, 謝謝大家!!
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-12-23 12:47:51 IP:203.73.xxx.xxx 未訂閱
aredfish 你好: 試試看底下這樣寫可不可以?? <>< face="Verdana, Arial, Helvetica">引言: [code] void __fastcall Test::ShowLiteral() { Form1->Label10->Caption = "Test Thread running"; } __fastcall Test::Test(bool CreateSuspended) : TThread(CreateSuspended) { FreeOnTerminate=true; Priority=tpNormal; Resume(); } void __fastcall Test::Execute() { //---- Place thread code here ---- Synchronize(ShowLiteral); // Form1->Label10->Caption = "Terminate Test Thread!!"; } //------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Test *T3=new Test(true); T3->FreeOnTerminate=true; } -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-12-23 13:10:33 IP:210.241.xxx.xxx 未訂閱
這樣子還是不行ㄝ!! 出現的錯誤訊息是 '__fastcall Test::ShowLiteral()' is not a member of 'Test'
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2002-12-23 13:14:15 IP:203.73.xxx.xxx 未訂閱
引言: 這樣子還是不行ㄝ!! 出現的錯誤訊息是 '__fastcall Test::ShowLiteral()' is not a member of 'Test'
aredfish 你好: 要宣告在你的 class Test 裡面(成為它的一個 method) --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#5 引用回覆 回覆 發表時間:2002-12-23 16:48:54 IP:210.241.xxx.xxx 未訂閱
謝謝版主大大, 這樣真的就可以執行了, 只要在.h檔中加入新函數的宣告就可以解決了。 我想再請教另一個問題,我要如何設計兩個按鈕, 其中一個是執行MultiThread 另外一個是停止MultiThread,而執行的那一個按鈕在完成一個工作後, 可再接受另一個工作, 我的困難是: 1. 若我在其中一個按鈕內寫入Test *T3=new Test(false), 那麼程式會開始執 行,但是卻停不下來, 因為若我在另一個按鈕中寫入T3->Terminate(), 那麼 對另一個按鈕來說T3就是一個新的變數,所以我得重新宣告, 但這麼一來, 兩 個按鈕之間就失去相互關係了。 2. 若我將Test *T3=new Test(false)放在程式一開始的地方(設為整體變數), 那麼我可以用T3->Resume(), 來啟動MultiThread, 並可用Terminate或 Suspend來停止或暫停MultiThread, 但問題是, 在MultiThread工作完成後 我便無法再利用剛剛裡面寫T3->Resume(), 的按鈕來再次啟動MultiThread 所以挺兩難的(還是我根本就搞錯方向了 ||>_<||) , 麻煩請各位大大再拔刀相助, 謝謝大家!!
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2002-12-23 23:36:31 IP:61.221.xxx.xxx 未訂閱
引言: 我想再請教另一個問題,我要如何設計兩個按鈕, 其中一個是執行MultiThread 另外一個是停止MultiThread,而執行的那一個按鈕在完成一個工作後, 可再接受另一個工作, 我的困難是: 1. 若我在其中一個按鈕內寫入Test *T3=new Test(false), 那麼程式會開始執 行,但是卻停不下來, 因為若我在另一個按鈕中寫入T3->Terminate(), 那麼 對另一個按鈕來說T3就是一個新的變數,所以我得重新宣告, 但這麼一來, 兩 個按鈕之間就失去相互關係了。 2. 若我將Test *T3=new Test(false)放在程式一開始的地方(設為整體變數), 那麼我可以用T3->Resume(), 來啟動MultiThread, 並可用Terminate或 Suspend來停止或暫停MultiThread, 但問題是, 在MultiThread工作完成後 我便無法再利用剛剛裡面寫T3->Resume(), 的按鈕來再次啟動MultiThread 所以挺兩難的(還是我根本就搞錯方向了 ||>_<||) , 麻煩請各位大大再拔刀相助, 謝謝大家!!
aredfish 你好: 我~~有點聽不太懂你的意思??< > 也沒有採用類似的方法做過~~< > 不過~~我在想喔~~如果用一個 Test 的 pointer array 應該能夠達成你的目的吧!! Test *T3[MAX_COUNT]; // 其中 MAX_COUNT 需要 define 但是~~如果要這樣做的話 那就要在程式碼中很小心的處理這個 array 了 --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#7 引用回覆 回覆 發表時間:2002-12-24 08:08:37 IP:210.241.xxx.xxx 未訂閱
我描述的不太好, 有點亂, 我舉個例子好了 假設我做一個從65535遞減到零的迴圈, 而這個迴圈是寫在MultiThread裡面(註一), 而我的Form上面有一個按鈕,一按下去他就會開始遞減(註二), 然後有另外一個按鈕當我按下去的時候不管他有沒有減到零(註三), 都會終止, 而若我再按 那個開始遞減的按鈕, 則他又會從65535開始重新遞減。 流程大概是這樣, 非常謝謝大家。 註一: 因為如果不寫在Thread裡面, 則程式在他減到零之前都不會動。 註二: 當他遞減的時候i--,也會把i的值show在Form上面,所以要用Synchronize 註三: 也就是說不管他是不是已經結束thread(計算完了); 目的是要讓使用者 可以隨時放棄正在進行中的動作。
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#8 引用回覆 回覆 發表時間:2002-12-24 08:25:01 IP:203.73.xxx.xxx 未訂閱
引言: 我描述的不太好, 有點亂, 我舉個例子好了 假設我做一個從65535遞減到零的迴圈, 而這個迴圈是寫在MultiThread裡面(註一), 而我的Form上面有一個按鈕,一按下去他就會開始遞減(註二), 然後有另外一個按鈕當我按下去的時候不管他有沒有減到零(註三), 都會終止, 而若我再按 那個開始遞減的按鈕, 則他又會從65535開始重新遞減。 流程大概是這樣, 非常謝謝大家。 註一: 因為如果不寫在Thread裡面, 則程式在他減到零之前都不會動。 註二: 當他遞減的時候i--,也會把i的值show在Form上面,所以要用Synchronize 註三: 也就是說不管他是不是已經結束thread(計算完了); 目的是要讓使用者 可以隨時放棄正在進行中的動作。
aredfish 你好: 看來我最近真是太不「善解人意」了 其實你這個問題可以不用寫 > < class="code"> long glCount=0; bool gbStop=false; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { gbStop=false; for(glCount=65535; glCount>=0; glCount--) { if(gbStop) break; Label1->Caption=IntToStr(glCount); Application->ProcessMessages(); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { gbStop=true; } -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#9 引用回覆 回覆 發表時間:2002-12-24 09:02:06 IP:210.241.xxx.xxx 未訂閱
啊!! 我懂了, 您建議以 "中斷" 的方式來處理, 非常謝謝!! 但請問一下中斷與多執行緒的適用時機大致上在哪裡?? 另外, 我看書上在使用Thread的Synchronize時, 好像都看不到有函數傳入傳出的行為, 譬如,傳入i到input函數,Synchronize(input(i)), 所以我有一個似是而非的觀念就是,如果我要在Thread中讀取或輸入VCL的值, 那麼我就要用整體變數, 這樣對嗎?? 謝謝您!!
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2002-12-24 09:24:36 IP:203.73.xxx.xxx 未訂閱
引言: 啊!! 我懂了, 您建議以 "中斷" 的方式來處理, 非常謝謝!! 但請問一下中斷與多執行緒的適用時機大致上在哪裡?? 另外, 我看書上在使用Thread的Synchronize時, 好像都看不到有函數傳入傳出的行為, 譬如,傳入i到input函數,Synchronize(input(i)), 所以我有一個似是而非的觀念就是,如果我要在Thread中讀取或輸入VCL的值, 那麼我就要用整體變數, 這樣對嗎?? 謝謝您!!
aredfish 你好: 以下內容轉貼自 BCB help < class="code"> TThread::Synchronize Executes a method call within the main VCL thread. typedef void __fastcall (__closure *TThreadMethod)(void); void __fastcall Synchronize(TThreadMethod &Method); Description Synchronize causes the call specified by Method to be executed using the main VCL thread, thereby avoiding multi-thread conflicts. If you are unsure whether a method call is thread-safe, call it from within the Synchronize method to ensure that it executes in the main VCL thread. Execution of the thread current is suspended while Method executes in the main VCL thread. Warning: Do not call Synchronize from within the main VCL thread. Doing so leads to an infinite loop. Note: You can also protect unsafe methods using critical sections or the multi-read exclusive-write synchronizer. 備註: 其實 bcb help 裡面有一些很重要的訊息 建議你自己查詢看看 --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
aredfish
一般會員


發表:47
回覆:41
積分:17
註冊:2002-12-04

發送簡訊給我
#11 引用回覆 回覆 發表時間:2002-12-24 09:59:25 IP:210.241.xxx.xxx 未訂閱
非常謝謝您的幫忙...
wolf_yalow
一般會員


發表:0
回覆:1
積分:0
註冊:2003-08-26

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-10-25 04:12:42 IP:218.162.xxx.xxx 未訂閱
版主大大您好~  剛剛看了板主回覆的那個方法,也就是不用執行緒的方法~ 但小弟心中還是有疑問,如果採用 aredfish 所提出用執行緒的做法, 那為何再一次 "T3->Resume(), 的按鈕來再次啟動MultiThread" 會不成功呢? 是因為 Thread 執行完畢自己 delete 所以無法再 RUN 了嗎?    Thread 執行完畢會自己 delete 是因為 FreeOnTerminate=true; 那如果不給 FreeOnTerminate=true 的話 Thread 會怎樣呢?     小弟想搞懂 BCB Thread 但是一直找不到詳細介紹, VC 的寫法又不一樣~ 很傷腦筋. 小弟只能爬文搜尋到有關 Thread 片段的文章..自己深深的閱覽不足.  可否請各位大大提供一些方向~ 感激不盡~< >< > =============================================================== >>>< face="Verdana, Arial, Helvetica">引言: 我描述的不太好, 有點亂, 我舉個例子好了 假設我做一個從65535遞減到零的迴圈, 而這個迴圈是寫在MultiThread裡面(註一), 而我的Form上面有一個按鈕,一按下去他就會開始遞減(註二), 然後有另外一個按鈕當我按下去的時候不管他有沒有減到零(註三), 都會終止, 而若我再按 那個開始遞減的按鈕, 則他又會從65535開始重新遞減。 流程大概是這樣, 非常謝謝大家。 註一: 因為如果不寫在Thread裡面, 則程式在他減到零之前都不會動。 註二: 當他遞減的時候i--,也會把i的值show在Form上面,所以要用Synchronize 註三: 也就是說不管他是不是已經結束thread(計算完了); 目的是要讓使用者 可以隨時放棄正在進行中的動作。
系統時間:2024-11-22 22:30:44
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!