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

有關Thread的問題?

尚未結案
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-21 01:29:07 IP:219.80.xxx.xxx 未訂閱
請問我使用了兩個thread,一個thread是做每0.1秒產生一個資料,另一個thread是每1秒清除一個資料且停留2秒. 程式碼如下:
Thread1:
void __fastcall Myth::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    Synchronize(WM);
    Sleep(100);
  }
}
void __fastcall Myth::WM()
{
  Form1->Memo1->Lines->Add(Time());
}
Thread2:
void __fastcall Myth2::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    Synchronize(CM);
    Sleep(1000);
  }
}
void __fastcall Myth2::CM()
{
  Form1->Memo1->Lines->Delete(0);
  Sleep(2000);
}
請問我該如何讓Thread一直做它的事,不會因為Thread2的停留2秒就也停住它的工作? 謝謝.
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-21 09:18:13 IP:221.169.xxx.xxx 未訂閱
因為你利用Synchronize(),將程式切換至MAIN THREAD,來處理ADD 和 DELETE,所以你如果你在 WD() 呼叫SLEEP,就會將MAIN THREAD佔住,解決方法如下,試試看修改下面藍色部分    
 Thread1: 
void __fastcall Myth::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    Synchronize(WM);
    Sleep(100);
  }
}
void __fastcall Myth::WM()
{
  Form1->Memo1->Lines->Add(Time());
}         Thread2: 
void __fastcall Myth2::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    Synchronize(CM);
    Sleep(3000);  //將下面的SLEEP(2000)改到這邊
  }
}
void __fastcall Myth2::CM()
{
  Form1->Memo1->Lines->Delete(0);
//  Sleep(2000);   將SLEEP 取消
}
========================= 大家一起快樂寫程式
seaturn99
版主


發表:69
回覆:427
積分:214
註冊:2003-08-25

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-21 10:31:29 IP:220.130.xxx.xxx 未訂閱
nlj859 您好 :    可以將以下 Delphi Code 轉成 BCB (抱歉,我的 C++ 的語法不太熟),將 Sleep 改成 Delay Function ,這樣可以正常使用 Synchronize 與 WaitForXXX 系列的 Win32 API ..    造成 dead lock 的原因如 lu 兄所述,主要由於 Synchronize 的實作方法,是由 Main Thread 的執行  ..     
procedure Delay(lMilliSeconds: longint);
var
  lStart: longint;
begin
  lStart := GetTickCount;
  while longint(GetTickCount) - lStart <= lMilliSeconds do
    Application.ProcessMessages;
end;
PS. 此段 Code 摘錄於蔡煥麟先生 Sample Code ---- 我只會兩件事,這也不會,那也不會 眼見不一定為真 ---- 發表人 - SouthWind 於 2004/09/21 10:35:33
andychang1690
資深會員


發表:20
回覆:694
積分:442
註冊:2003-03-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-21 11:22:10 IP:221.169.xxx.xxx 未訂閱
引言: nlj859 您好 : 可以將以下 Delphi Code 轉成 BCB (抱歉,我的 C 的語法不太熟),將 Sleep 改成 Delay Function ,這樣可以正常使用 Synchronize 與 WaitForXXX 系列的 Win32 API .. 造成 dead lock 的原因如 lu 兄所述,主要由於 Synchronize 的實作方法,是由 Main Thread 的執行 ..
procedure Delay(lMilliSeconds: longint);
var
  lStart: longint;
begin
  lStart := GetTickCount;
  while longint(GetTickCount) - lStart <= lMilliSeconds do
    Application.ProcessMessages;
end;
PS. 此段 Code 摘錄於蔡煥麟先生 Sample Code ---- 我只會兩件事,這也不會,那也不會 眼見不一定為真 ---- 發表人 - SouthWind 於 2004/09/21 10:35:33
翻譯成BCB
void __fastcall TForm1::Delay(double         lMilliSeconds)
{
  double        lStart;
  lStart = GetTickCount();
  do {
    Application->ProcessMessages();
  }  while (double        (GetTickCount()) - lStart <= lMilliSeconds );
}
請參考!
Andy Chang
------
Andy Chang
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-21 11:53:51 IP:219.80.xxx.xxx 未訂閱
Hello all,    實際如果是像以下這樣呢?
Thread2:
void __fastcall Myth2::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    Synchronize(CM);
    Sleep(1000);
  }
}
//---------------------------------------------------------------------------
void __fastcall Myth2::CM()
{

  _di_IDataIn aaa;
  Form1->HTTPRIO1->QueryInterface(aaa);
  aaa->WriteData(Form1->Memo1->Lines->Strings[0],1);
  delete aaa;      Form1->Memo1->Lines->Delete(0);
}
藍色的字部份會花掉幾秒鐘的時間,這時,Thread1也會停住不動. 那該如何處理這個問題? 謝謝.
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-09-21 16:41:15 IP:221.169.xxx.xxx 未訂閱
Thread2:
void __fastcall Myth2::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    Synchronize(CM);
    Sleep(1000);
  }
}
//---------------------------------------------------------------------------
void __fastcall Myth2::CM()
{

  _di_IDataIn aaa;
  Form1->HTTPRIO1->QueryInterface(aaa);
  aaa->WriteData(Form1->Memo1->Lines->Strings[0],1);
  delete aaa;      Form1->Memo1->Lines->Delete(0);
}
問一下,HTTPRIO1有非同步的FUNCTION(呼叫後立即返回,不等動作完成) 如果有的話,直接呼叫那個FUNCTION即可...... 如果沒有的話,就必須查一下HTTPRIO1是Thread Safe 的物件嗎? 如果是,就不用呼叫Synchronize(),直接在THREAD之中操作該物件即可 如果不是Thread Safe....恕小弟才疏學淺,一時之間沒有想到更好的辦法,各大大有好的意見請提出來大家參考 ========================= 大家一起快樂寫程式
nlj859
資深會員


發表:139
回覆:375
積分:322
註冊:2004-03-20

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-09-22 12:48:50 IP:219.80.xxx.xxx 未訂閱
引言:
Thread2:
void __fastcall Myth2::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    Synchronize(CM);
    Sleep(1000);
  }
}
//---------------------------------------------------------------------------
void __fastcall Myth2::CM()
{

  _di_IDataIn aaa;
  Form1->HTTPRIO1->QueryInterface(aaa);
  aaa->WriteData(Form1->Memo1->Lines->Strings[0],1);
  delete aaa;      Form1->Memo1->Lines->Delete(0);
}
問一下,HTTPRIO1有非同步的FUNCTION(呼叫後立即返回,不等動作完成) 如果有的話,直接呼叫那個FUNCTION即可...... 如果沒有的話,就必須查一下HTTPRIO1是Thread Safe 的物件嗎? 如果是,就不用呼叫Synchronize(),直接在THREAD之中操作該物件即可 如果不是Thread Safe....恕小弟才疏學淺,一時之間沒有想到更好的辦法,各大大有好的意見請提出來大家參考 ========================= 大家一起快樂寫程式
請問什麼是Thread Safe 的物件?該如何查呢?請指教. 因為這一行
aaa->WriteData(Form1->Memo1->Lines->Strings[0],1);
它的呼叫和回覆的時間可能要花0.5秒以上的時間,所以程式會等它做完才會繼續下一行. 所以不曉得是跟什麼比較有關係. 謝謝.
seaturn99
版主


發表:69
回覆:427
積分:214
註冊:2003-08-25

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-09-22 17:06:01 IP:220.130.xxx.xxx 未訂閱
引言: 請問什麼是Thread Safe 的物件?該如何查呢?請指教. 因為這一行
aaa->WriteData(Form1->Memo1->Lines->Strings[0],1);
它的呼叫和回覆的時間可能要花0.5秒以上的時間,所以程式會等它做完才會繼續下一行. 所以不曉得是跟什麼比較有關係. 謝謝.
先解釋藍色的字部份會花費一些時間且 Thread 停住的現象,由於Synchronize 是由 Main Thread 執行,故如果產生多個 Myth2 , Myth2::CM() 便會以類似 Queue 的方式順序執行,且一次只執行一個 Myth2::CM() ,再加上 Sleep 的影響,您可以嘗試發起 5 與 10 個 Thread ,停滯現象應該會加重 .. 若只執行一個 Thread 測出 aaa->WriteData(Form1->Memo1->Lines->Strings[0],1); 花費 0.5 sec ,那執行 CM() 至少就需要 0.5 sec 以上,這也是一個停滯現象的因素 .. Thread Safe 指的是,在 Multi-Thread 區段的 Code 中,有對 Thread 而言可存取的全域變數或具執行順序的 Code 區段,若有透過同步機制保護的,便是 Thread Safe ,反之則為 unsafe ,同步保護機制,如 Synchronize , Mutex, Critical Section, Semphore 等等 .. 若 Myth2::CM() 是必須以同步機制保護的,又不想讓 Thread 在 Main Thread 中類 Queue 等待的執行,那可以改寫 Synchronize ,利用 Critical Section 或 Mutex 保護 CM() 中需要保護的地方,這樣可以讓情況改善一點 .. 但若 CM() 中有耗費執行時間的瓶頸在的話,情況便較難改善,可能要另換思維,改變程式的架構 .. 若是根本不需要同步保護,那便如 lu 兄所述,拿掉 Synchronize , 直接執行 CM() 即可..
Thread2:    // 宣告 Global hMutex : THandle;
// 在發起 Thread2 之前,Create 一個 Mutex => hMutex = CreateMutex(nil,false,nil);    void __fastcall Myth2::Execute()
{
  //---- Place thread code here ----
  while (1)
  {
    
    // Synchronize(CM);
    CM();
    
    Sleep(1000);
  }
}    void __fastcall Myth2::CM()
{
  _di_IDataIn aaa;
  Form1->HTTPRIO1->QueryInterface(aaa);
  
  if WaitForSingleObject(hMutex,INFINITE) == WAIT_OBJECT_0 {
     aaa->WriteData(Form1->Memo1->Lines->Strings[0],1);
  }
  ReleaseMutex(hMutex);
    
  delete aaa;
  
  Form1->Memo1->Lines->Delete(0);
}    // 記得要 CloseHandle(hMutex);    
PS. 假設只有紅色區段需要保護 ---- 我只會兩件事,這也不會,那也不會 眼見不一定為真 ---- 發表人 - SouthWind 於 2004/09/22 17:14:13
系統時間:2024-07-03 8:43:01
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!