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

多執行緒(均帶無窮迴圈)能同時執行嗎?

答題得分者是:wameng
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-17 15:38:24 IP:61.221.xxx.xxx 未訂閱
unit ReadThread;    interface    uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;    type
 TReadMessage = class(TThread)
  private
    procedure ReceveMessage;
    function  DelayTime(Delay:word):Boolean;
  protected
    procedure Execute; override;
  end;    implementation    Uses Linwin;    procedure TReadMessage.Execute;
begin
  Synchronize(ReceveMessage);
end;    procedure TReadMessage.ReceveMessage;
begin
while ReadThreadSw=True do
 begin
   ......to do Something;
   Application.ProcessMessages;
 end;//while end;
end;
小的有二隻類似的執行緒,檢查過並無存取相同的全域變數 但在主程式中以如下方式建立,
 ReadThreadSw:=True;
 ReadMessage:=TreadMessage.Create(True);
 Threadsw:=True;
 ReadImss:=TReadImss.Create(True);
 ReadImss.Resume;
 ReadMessage.Resume;
先被執行(Resume的執行緒動作無誤,單獨拆開各自執行緒也無問題,但同時Resume後,較晚被執行的執行緒則會失效,請問是何原因造成?該如何解決呢? 謝謝~~ 搞不懂!搞不懂!永遠都搞不懂!!
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-17 16:08:37 IP:220.135.xxx.xxx 未訂閱
引言:
   ......to do Something;
   Application.ProcessMessages;
在thread 寫作中粉多VCL物件應該都不能用(TControl,TList,...) Application應改也算是吧 你把Application.ProcessMessages拿掉試試(Thread不像主程式會佔用CPU資源 本身會很快交出控制權讓別的程式可以處理Message) 如果還是覺得你的while迴圈耗太多時間的話可考慮用sleep指令暫時交出thread控制權 混心雜欲 棄修身~唉
------
唉~
wameng
版主


發表:31
回覆:1336
積分:1188
註冊:2004-09-16

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-17 17:02:09 IP:61.222.xxx.xxx 未訂閱
補充: 使用Synchronize()方法 ,可以透過它讓執行緒的一些函數能夠在主執行緒(Process) 中執行。 在該方法又使用 Application.ProcessMessages 不是很奇怪嗎!!!
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-11-17 17:05:25 IP:61.221.xxx.xxx 未訂閱
HI Speedup大大你好 一但拿掉了application.processmessage 整個程式就被Hold住了 用sleep的話會lag的很嚴重所以有另改用
function TReadMessage.DelayTime(Delay:word):Boolean;
var
dtime:DWORD;
begin
dtime:=GetTickCount();//取得震盪器的次數
while GetTickCount()-dtime的方式單隻執行緒並無上述的問題 
這二隻執行緒一隻用來檢查mailslot有無新訊息,一隻用來檢查access資料有無執行時間已到,時間到則觸發執行程序。
單隻執行緒拆成二個執行檔呼叫皆是正常無誤的。
還是謝謝大大提供思考的方向    搞不懂!搞不懂!永遠都搞不懂!!
        
hahalin
版主


發表:295
回覆:1698
積分:823
註冊:2002-04-14

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-11-17 17:11:23 IP:218.170.xxx.xxx 未訂閱
如果兩個執行緒要一方等對方完成什麼後,才進行自己的作業 那麼也許執行緒同步化是個做法
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-11-17 17:12:10 IP:61.221.xxx.xxx 未訂閱
wameng大大你好 大大說的我並不是很懂,使用同步不是只是錯開相同變數存取嗎?避開死結? 不使用application.processmessage 該如何避開程式被hold?? 還請大大指教 搞不懂!搞不懂!永遠都搞不懂!!
wameng
版主


發表:31
回覆:1336
積分:1188
註冊:2004-09-16

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-11-17 17:12:41 IP:61.222.xxx.xxx 未訂閱
插花一下! 正確作法應該在 Thread.execute 中等待 當符合條件才 Synchronize(ReceveMessage); 不然,這樣使用Thread 有何意義! 另外在 Thread 需要等待用 Sleep 或 WaitSingleObject 方法。不會影響到 Process
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-11-17 17:20:30 IP:61.221.xxx.xxx 未訂閱
wameng,hahalin大大 但我二隻執行緒皆不需等待對方(並無存取共同變數) 因為執行緒主要動作用來處理電話同時打進或有其他線路撥出 進線的電話我需要處理他進線的程序 另一執行緒除了處理撥出還得看看資料庫裡是不是有預定時間到需要自動撥出的語音通知,沒有用Timer作 是為了以後多線不同進線可能有不同的處理流程。 應該可以說
procedure TReadMessage.Execute;
begin
  ReceveMessage;
end;
我的程式部份其實是不用同步化的 搞不懂!搞不懂!永遠都搞不懂!! 發表人 - mine 於 2004/11/17 17:25:15
seaturn99
版主


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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-11-17 17:37:22 IP:220.130.xxx.xxx 未訂閱
引言:
unit ReadThread;    interface    uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;    type
 TReadMessage = class(TThread)
  private
    procedure ReceveMessage;
    function  DelayTime(Delay:word):Boolean;
  protected
    procedure Execute; override;
  end;    implementation    Uses Linwin;    procedure TReadMessage.Execute;
begin
  Synchronize(ReceveMessage);
end;    procedure TReadMessage.ReceveMessage;
begin
while ReadThreadSw=True do
 begin
   ......to do Something;
   Application.ProcessMessages;
 end;//while end;
end;
小的有二隻類似的執行緒,檢查過並無存取相同的全域變數 但在主程式中以如下方式建立,
 ReadThreadSw:=True;
 ReadMessage:=TreadMessage.Create(True);
 Threadsw:=True;
 ReadImss:=TReadImss.Create(True);
 ReadImss.Resume;
 ReadMessage.Resume;
先被執行(Resume的執行緒動作無誤,單獨拆開各自執行緒也無問題,但同時Resume後,較晚被執行的執行緒則會失效,請問是何原因造成?該如何解決呢? 謝謝~~ 搞不懂!搞不懂!永遠都搞不懂!! < face="Verdana, Arial, Helvetica"> mine 您好 : 答案在紅色的地方, wameng Sir 提到一個重點: "使用Synchronize()方法,可以透過它讓執行緒的一些函數能夠在主執行緒(Process)中執行。" Delphi 利用 Message 機制巧妙的設計了 Synchronize() 這個函式,讓傳入執行的 Code 在 Main Thread 執行... 所以,您可以發現當 ReadImss.Resume; 執行時,您的 ReceveMessage 開始進入無限迴圈,但是因為透過 Synchronize 執行,使得這段 Code 在 Main Thread 中執行,所以 ReadMessage.Resume; 要等無限迴圈結束才會執行.. 您撰寫的 Code 的邏輯,等同於沒有發起 Thread ,順序執行 ReadImss.Resume; ReadMessage.Resume; .. 如果沒有同步化的問題,所以把 Synchronize 拿掉就可以順利 work 了,建議還是要撰寫一個結束 Thread 的機制,讓 User 可以透過操作關閉 Thread ,或是主程式全部關閉,這樣程式結構比較優雅些... 不過透過一些 Flag 變數控制,必須是 Global ,這時候就要考慮競爭的問題了,需要一些同步機制.. 表達的不好,請見諒,希望能幫助您理解此一現象,之前,我也被這個方便的 function 困擾過一小段時間... ---- 我只會兩件事,這也不會,那也不會 眼見不一定為真 ---- 發表人 - SouthWind 於 2004/11/17 17:52:47
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-11-17 17:38:11 IP:61.221.xxx.xxx 未訂閱
我想懂了....謝謝大大糾正我錯了好久的觀念 改完程式了 回來寫銘謝感言....這一錯....錯了二年(忽然想找個地洞鑽下去)...居然沒有被人發現(可能是同事不好意思指正我:
系統時間:2024-06-29 15:45:30
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!