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

執行緒結束程式問題

尚未結案
renth555
一般會員


發表:32
回覆:65
積分:19
註冊:2003-02-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-08-27 23:43:59 IP:61.56.xxx.xxx 未訂閱
void __fastcall TMyThread::Execute()
{
  //程式碼......
        Form1->Close();
} 
我該如何讓執行緒程式跑完即自己關必整個程式呢 我在最後一行打 exit(); OR close 都會有錯誤 謝謝
李國維
高階會員


發表:42
回覆:287
積分:235
註冊:2003-02-07

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-08-28 12:59:04 IP:61.62.xxx.xxx 未訂閱
因為你是用Form去include thread所以你可以試試 再thread中加入一各判斷ㄉflag.當thread執行完一次後 把flag設為true.再由主form去check該flag是否為ture 如果是ㄉ話再去關閉該程式
renth555
一般會員


發表:32
回覆:65
積分:19
註冊:2003-02-17

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-09-01 21:43:01 IP:61.56.xxx.xxx 未訂閱
真的沒有更好方法嗎 我目前是在 Form1->Timer1 做真假判斷 李國維 前輩所說方法是我目前所作的方法 謝謝
李國維
高階會員


發表:42
回覆:287
積分:235
註冊:2003-02-07

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-09-02 11:44:20 IP:211.22.xxx.xxx 未訂閱
引言: 真的沒有更好方法嗎 我目前是在 Form1->Timer1 做真假判斷 李國維 前輩所說方法是我目前所作的方法 謝謝
ㄏㄏ.基本上應該都是要再Form1來判斷後關閉. 所以我覺ㄉTimer是最快ㄉ方法. 你如果覺ㄉ不滿意.你可以試試看用TEvent. 因為TEvent是以全域範圍所建立ㄉ.所以它能當作訊號 並讓所有ㄉ執行緒使用.
tpchen
一般會員


發表:3
回覆:7
積分:2
註冊:2003-08-24

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-09-02 16:01:00 IP:211.75.xxx.xxx 未訂閱
請在您的Form->Close(); 之前加入此一Windows API 函式呼叫 WaitForMultipleObjects(i, (HANDLE *)hThread, TRUE, INFINITE) ; ^^^^^^^^^^^^^^^^^^ 請參考MS MSDN的說明 你的問題是發生在你所有的執行緒尚未執行完畢,而你的主Process又要結束程式。因此,你必須在主Process的結束呼叫之前呼叫WaitForMultipleObjects()。 希望對您有用~
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-09-02 23:54:28 IP:61.224.xxx.xxx 未訂閱
直接用 TThread 裡的 WaitFor() 不是更方便.. 還可以拿到Thread return value --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-09-03 10:20:31 IP:211.76.xxx.xxx 未訂閱
這裡有一篇很不錯的TThread文章參考看看吧 http://www.informit.com/isapi/product_id~{5FE8140F-8B61-4B95-A368-878C5F963B92}/element_id~{37E9892B-008B-4D60-8618-2085E3A5F005}/st~{3FAD3499-20A6-4782-9A96-05825F8E6E5B}/content/articlex.asp
/*開心的事情別隱藏在心裡,分享給別人知道會更快樂的*/
/*得到新知識別隱藏在心裡,分享給別人了解會更清楚的*/
artist1002
高階會員


發表:2
回覆:155
積分:151
註冊:2002-09-26

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-09-03 23:07:56 IP:211.76.xxx.xxx 未訂閱
你可以做一個自訂的結束函數在主程式裡 然後在new thread之後把 TThread->OnTerminate 這個 Event 指向自訂的結束函式 那在 Thread 結束的時候會去執行這個函式 然後你在函式裡寫Close(); 如:
void __fastcall TMainForm::ThreadTerminate(void)
{
    Close();
}
在使用Thread的時候    TMyThread *thread;
thread = new TMyThread(true); //建立新執行緒的時候是suspend的
thread->FreeOnTerminate = true; //建議使用, 因為你執行緒結束的時候就要關閉視窗了.
thread->OnTerminate = ThreadTerminate; //把OnTerminate指向自訂函式
thread->Resume(); //開始執行    
miyu
中階會員


發表:13
回覆:96
積分:91
註冊:2003-05-01

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-09-04 00:50:55 IP:61.224.xxx.xxx 未訂閱
引言: 你可以做一個自訂的結束函數在主程式裡 然後在new thread之後把 TThread->OnTerminate 這個 Event 指向自訂的結束函式 那在 Thread 結束的時候會去執行這個函式 然後你在函式裡寫Close(); 如:
void __fastcall TMainForm::ThreadTerminate(void)
{
    Close();
}
在使用Thread的時候    TMyThread *thread;
thread = new TMyThread(true); //建立新執行緒的時候是suspend的
thread->FreeOnTerminate = true; //建議使用, 因為你執行緒結束的時候就要關閉視窗了.
thread->OnTerminate = ThreadTerminate; //把OnTerminate指向自訂函式
thread->Resume(); //開始執行    
不過我覺得理論上會有一點不妥... TThread 在建構的時候會去呼叫 BeginThread() 建立一個 Thread, 然後把一個不屬於任何 class 的 function 當成 ThreadFunc 的參數丟進去. ThreadFunc 就是當這個 Thread 在執行的時候, 被執行到的程式. 然後, 這個 function 會去呼叫你的 Thread class 中的 Execuute function, 這是一個 abstract virtual function, 換句話說, 後代一定要改寫這個函式. 這個函式裡面是你的 Thread class 要執行的程式碼. 如果這個function return了, 您的 Thread 也準備要結束了. 就是說:
TThread.Create() 
begin
  ...
  BeginThread(..., @ThreadProc, ...);       // 建立 Thread, 並指定執行 ThreadProc()
  ...
end    function ThreadProc(Thread: TThread): Integer;
begin
  ...
  TThread.Execute() // 實際上是呼叫到 TThreadChild.Execute();
  Result := Thread.FReturnValue // 對應到 ReturnValue, 此為 thead return value
  Thread.FFinished := true;     // Thread 工作完成了
  Thread.DoTerminate;           // 如果 OnTerminate function 有指定, 以 
                                // synchronize 的方式呼叫您的 Terminate function
  if FreeThread then Thread.Free; // 如果 FreeOnTerminate = true, 解構 TThread Class (執行 TThread.Destroy)
  EndThread(Result);            // 傳回 Thread Return value                                
  ...
end
這邊會產生一個問題, 你在 OnTerminate 中去呼叫 Close(); 結束程式, 將產生典型的競速問題. 如果 Thread (應該說 ThreadProc()) 先執行完, 那麼就相安無事. 如果是 Process 先結束, 那麼 thread 就會碰到owner process 已經死亡的情況, 這樣子很容易產生問題. 另外, 這樣子寫也有可能造這個 Thread 沒有被 destroy 掉就結束程序的可能性. 單顆 cpu 的情況, 發生率是不太高. 不過 multi-processor 就很難講了. 建議要使用 Thread, Kernel object, 應該盡量要等待他們正確的回返/結束才結束. 除非迫不得已才動用非常手段.. --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
artist1002
高階會員


發表:2
回覆:155
積分:151
註冊:2002-09-26

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-04-07 23:33:04 IP:211.76.xxx.xxx 未訂閱
引言:
引言: 你可以做一個自訂的結束函數在主程式裡 然後在new thread之後把 TThread->OnTerminate 這個 Event 指向自訂的結束函式 那在 Thread 結束的時候會去執行這個函式 然後你在函式裡寫Close(); 如:
void __fastcall TMainForm::ThreadTerminate(void)
{
    Close();
}
在使用Thread的時候    TMyThread *thread;
thread = new TMyThread(true); //建立新執行緒的時候是suspend的
thread->FreeOnTerminate = true; //建議使用, 因為你執行緒結束的時候就要關閉視窗了.
thread->OnTerminate = ThreadTerminate; //把OnTerminate指向自訂函式
thread->Resume(); //開始執行    
不過我覺得理論上會有一點不妥... TThread 在建構的時候會去呼叫 BeginThread() 建立一個 Thread, 然後把一個不屬於任何 class 的 function 當成 ThreadFunc 的參數丟進去. ThreadFunc 就是當這個 Thread 在執行的時候, 被執行到的程式. 然後, 這個 function 會去呼叫你的 Thread class 中的 Execuute function, 這是一個 abstract virtual function, 換句話說, 後代一定要改寫這個函式. 這個函式裡面是你的 Thread class 要執行的程式碼. 如果這個function return了, 您的 Thread 也準備要結束了. 就是說:
TThread.Create() 
begin
  ...
  BeginThread(..., @ThreadProc, ...);       // 建立 Thread, 並指定執行 ThreadProc()
  ...
end    function ThreadProc(Thread: TThread): Integer;
begin
  ...
  TThread.Execute() // 實際上是呼叫到 TThreadChild.Execute();
  Result := Thread.FReturnValue // 對應到 ReturnValue, 此為 thead return value
  Thread.FFinished := true;     // Thread 工作完成了
  Thread.DoTerminate;           // 如果 OnTerminate function 有指定, 以 
                                // synchronize 的方式呼叫您的 Terminate function
  if FreeThread then Thread.Free; // 如果 FreeOnTerminate = true, 解構 TThread Class (執行 TThread.Destroy)
  EndThread(Result);            // 傳回 Thread Return value                                
  ...
end
這邊會產生一個問題, 你在 OnTerminate 中去呼叫 Close(); 結束程式, 將產生典型的競速問題. 如果 Thread (應該說 ThreadProc()) 先執行完, 那麼就相安無事. 如果是 Process 先結束, 那麼 thread 就會碰到owner process 已經死亡的情況, 這樣子很容易產生問題. 另外, 這樣子寫也有可能造這個 Thread 沒有被 destroy 掉就結束程序的可能性. 單顆 cpu 的情況, 發生率是不太高. 不過 multi-processor 就很難講了. 建議要使用 Thread, Kernel object, 應該盡量要等待他們正確的回返/結束才結束. 除非迫不得已才動用非常手段.. --- 小葵..小葵有很多的夢想 等待薰下班回家, 並準備晚飯跟洗澡水 薰回家的時候, 對你說一聲 歡迎回家 在休息的日子, 兩個人坐在屋外的走廊上, 品嚐著我親自作的點心 薰如果累了, 替他搥搥肩; 冷了, 和薰一起擠著被爐 但是, 但是... 小葵最大的心願是...成為薰的..成為薰的妻子
嗯...沒錯,我之前想得不夠周詳. 的確會產生競速問題. 在這問題還是應該使用你之前所說的Waitfor()的方法來做比較正確.
jimmy_and_you
初階會員


發表:20
回覆:74
積分:33
註冊:2003-05-12

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-04-08 14:39:56 IP:203.70.xxx.xxx 未訂閱
我之前也遇到過相同的問題,想了好久有試出一個方法: 在Thread結束之前,送一個Message給主視窗,主視窗收到後用WaitForSingleObject()等待Thread結束,然後在結束程,大致的範例code如下
 
__fastcall TForm1::TForm1(TComponent *Owner)
        : TForm(Owner)
{
    WindowProc = MyWndProc;
}
//---------------------------------------------------------------------------    void __fastcall TForm1::MyWndProc(TMessage &Message)
{
    if (Message.Msg == FINISH_THREAD/*user define message*/)
    {
                WindowProc = WndProc;                //Unhook 以免下一行lock住message的處裡
                WaitForSingleObject((HANDLE)MyThread->Handle, INFINITE) );
                Application->Terminate();
    }
    WndProc(Message);
}
//---------------------------------------------------------------------------    void __fastcall TestThread::Execute()
{
    //---- Place thread code here ----
        :
        :
        :
        :        //at last
    PostMessage( (HANDLE) Form1->Handle, FINISH_THREAD,        0, 0);  
    this->FreeOnTerminate = true;    }
//---------------------------------------------------------------------------
希望對大家有幫助
系統時間:2024-05-18 12:42:36
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!