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

如何同步執行Thread ??

答題得分者是:william
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-17 09:46:21 IP:61.218.xxx.xxx 未訂閱
我有一個Thread ,我想同一時間同時執行Thread,要如何做??? ex: begin Thread1 := TMoveData.Create(ADOConnection1,'01'); Thread2 := TMoveData.Create(ADOConnection1,'02'); end;
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-17 10:29:03 IP:147.8.xxx.xxx 未訂閱
Any problem? Create 2 threads and let them run. You could use citical section/mutex/semaphore to do the synchorization.
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-17 10:47:32 IP:61.218.xxx.xxx 未訂閱
引言: Any problem? Create 2 threads and let them run. You could use citical section/mutex/semaphore to do the synchorization.
Dear william : 不懂ㄟ!!我太笨了,我的寫法不是會等第一個Thread執行完, 才會繼續第二個Thread的create,還是我誤會意思, 到底是如何work的呢?? 這樣問好了,我的thread是一個查詢資料,若我 Create 2 threads ,這個查詢會是同時查詢嗎??還是等第一個Thread查完後才繼續第二個Thread ????
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-17 10:59:13 IP:147.8.xxx.xxx 未訂閱
Unless you explicitly suspend the threads. They are running side by side. Beware of using DB inside a thread, I think ADO may be fine but BDE may has some problems.
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-17 11:18:46 IP:61.218.xxx.xxx 未訂閱
我是使用ADO去連接資料庫的,我的Thread是作insert data,我的資料量又很大, 所以我想一次自動啟動12個thread,那樣可以縮點時間, 好樣紅碼以那支程式範例, 只示我想同時就啟動12個thread,那可縮短12倍的時間, 不知要如何寫程式???可否請高手指點一下,寫些範例程式碼給我看一下??? 發表人 - cyl 於 2003/04/17 11:20:12
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-17 11:36:14 IP:61.218.xxx.xxx 未訂閱
Post 上我的程式碼    unit Unit2;    interface uses   Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF},    DB, ADODB, DBTables,Gauges,StdCtrls,Forms,SysUtils; type   TMoveData = class(TThread)   private     Gauge:TGauge;     ADOStoredProc1: TADOStoredProc;     ADOQuery1: TADOQuery;     Table1:TTable;     iThread :string;   protected   procedure Execute; override;   procedure GiveAnswer; // 告訴主程式Query已完成   public     OkString:string; // 用來宣告動作完成用     constructor Create(Source:TADOConnection; i_agym:String); //    destructor Destroy; override;   end;    implementation constructor TMoveData.Create(Source:TADOConnection;i_agym:String); begin  iThread:=i_agym; //copy file         CopyFile(Pchar('D:\khmfdown\source\khmfma.DBF'),                               PChar('D:\khmfdown\thisweek\khmfma'+iThread+'.DBF'),False);                 CopyFile(Pchar('D:\khmfdown\source\khmfag.DBF'),                               PChar('D:\khmfdown\thisweek\khmfag'+iThread+'.DBF'),False);                 CopyFile(Pchar('D:\khmfdown\source\khmfhe.DBF'),                               PChar('D:\khmfdown\thisweek\khmfhe'+iThread+'.DBF'),False);                 CopyFile(Pchar('D:\khmfdown\source\khmfri.DBF'),                               PChar('D:\khmfdown\thisweek\dbf\khmfri'+iThread+'.DBF'),False);                 CopyFile(Pchar('D:\khmfdown\source\khmfad.DBF'),                               PChar('D:\khmfdown\thisweek\dbf\khmfad'+iThread+'.DBF'),False);                 CopyFile(Pchar('D:\khmfdown\source\khmftr.DBF'),                               PChar('D:\khmfdown\thisweek\khmftr'+iThread+'.DBF'),False);                 CopyFile(Pchar('D:\khmfdown\source\khmflo.DBF'),                               PChar('D:\khmfdown\thisweek\khmflo'+iThread+'.DBF'),False); //----------------------end copty file //  ADOStoredProc1:=TADOStoredProc.Create(Application);   ADOquery1     :=TADOQuery.Create(Application);   ADOquery1.Connection:= Source; {   ADOStoredProc1.Connection:= Source;   ADOStoredProc1.ProcedureName :='P_KHMFDOWN';   ADOStoredProc1.Parameters.AddParameter.Name :='i_agym';   ADOStoredProc1.Parameters.ParamByName('i_agym').value:=iThread;   }   table1:=TTable.Create(Application);   Table1.TableName :='D:\khmfdown\thisweek\khmfma'+iThread+'.DBF';   ADOquery1.SQL.Clear;   ADOquery1.SQL.Add ('truncate table tb_main'+iThread+'  drop storage');   ADOquery1.ExecSQL ;   inherited Create(false); end; procedure TMoveData.Execute;     procedure AddRec;   var     i,j:integer;   begin   ADOquery1.Open ;   table1.Open ;       with ADOquery1 do begin     for  j :=0 to ADOquery1.RecordCount -1 do begin        table1.Append;        for i:=0 to FieldCount-1 do            table1.FieldByName(Fields.Fields[i].FieldName).Value:=Fields.Fields[i].Value;       ADOquery1.Next ;     end;       table1.Edit;       table1.Post ;    end;      end; begin   //ADOStoredProc1.ExecProc ;   {   ADOquery1.SQL.Clear;   ADOquery1.SQL.Add('insert into ag.tb_main@dev2(select /*+ Rule */ polno1,polno2,bid,bname,bsex,bborndt,bage, ');   ADOquery1.SQL.Add('aid,aname,sex,aborndt,age,job,honydt,lab1,lab2, ');   ADOquery1.SQL.Add('lab3,acym,agym,agdt,poldt,perd,bsf,subbpm,disgrp, ');   ADOquery1.SQL.Add('disbpm,bpm,bpmtot,pay,paytype,ara,arazip,paytime, ');   ADOquery1.SQL.Add('paydt,nextdt,style,excover,clcod,polsele,adjcod, ');   ADOquery1.SQL.Add('grpno,no80m,spno,scry,autcod,unpcod,tracod,fovcod, ');   ADOquery1.SQL.Add('txdt,expcod,sc,clmsc,ctend,prsc,anntime,lapsdt  ');   ADOquery1.SQL.Add('from qq.tab_khmf_main@dev2 ');   ADOquery1.SQL.Add('where  mod(round(poldt/100),100)='+iThread+')');   ADOquery1.ExecSQL ;   }   ADOquery1.SQL.Clear;   ADOquery1.SQL.Add('select /*+ Rule */ b.polno1,b.polno2,b.agcod, ');   ADOquery1.SQL.Add('b.agid,b.agname,b.divdept,b.divunit,b.divzone,b.divteam ');   ADOquery1.SQL.Add('from ag.tb_main'+iThread+'@dev2 a,qq.tab_khmf_agid@dev2 b ');   ADOquery1.SQL.Add('where a.polno1=b.polno1 and a.polno2=b.polno2 '); //  ADOquery1.ExecSQL ;   AddRec;   //ADOStoredProc1.Free;   ADOquery1.Free;   Table1.Free;   Synchronize(GiveAnswer); // 宣告完成 end; procedure TMoveData.GiveAnswer; begin   OKString:='OK' end; end.    unit Unit1;    interface    uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs,  DB, ADODB, DBTables,StdCtrls;    type   TForm1 = class(TForm)     Button1: TButton;     BatchMove1: TBatchMove;     ADOConnection1: TADOConnection;     ADOStoredProc1: TADOStoredProc;     Label1: TLabel;     Edit1: TEdit;     procedure Button1Click(Sender: TObject);   private     { Private declarations }   public     { Public declarations }   end;    var   Form1: TForm1;    implementation    uses Unit2;    {$R *.dfm}    procedure TForm1.Button1Click(Sender: TObject); var   Thread1 :TMoveData;    Time1:TDateTime;    F:Double; begin    // 此地方就是我想同時可以讓12個thread跑完,但是不知如何寫??? //我的參數是01~12 Time1:=now; Thread1 := TMoveData.Create(ADOConnection1,'01'); while Thread1.OKString='' do // 還未執行完成時 begin f:=now()-Time1; f:=f * (24*60.0); label1.caption:=format('所花時間:%.2f分',[f]); Application.processmessages; end; end; end.
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-04-17 12:00:13 IP:147.8.xxx.xxx 未訂閱
I think something like:
var
    Threads: array[0..11] of TMoveData;
{...}
    for i := 0 to 11 do
        Threads[i] := TMoveData.Create(ADOConnection1,Format('%.2d',[i]));
    { ... wait and check if all threads are completed/terminated }
    for i := 0 to 11 do
        Threads[i].Free
The time taken would better be measured within the thread. BTW, .DBF is a dBase file, would 12 concurrent threads accessing it being too many? Have you tested your MoveData thread? I think you should call CoInitialize and CoUninitalize within it in order to use ADO.
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-04-17 14:33:58 IP:61.218.xxx.xxx 未訂閱
Dear William 我若想在畫面上顯示每一個Thread 的執行時間 while Thread1.OKString='' do // 還未執行完成時 begin f:=now()-Time1; f:=f * (24*60.0); label1.caption:=format('所花時間:%.2f分',[f]); Application.processmessages; end; 此段程式碼要加在何處呢???
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-04-17 14:44:15 IP:147.8.xxx.xxx 未訂閱
In the thread's Execute method, e.g. StartTime := Now; {... start the work ... } Time1 := Now - StartTime; Synchorize(UpdateLabel); // if you need to update GUI for display {... work is done ... }
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-04-17 16:35:06 IP:61.218.xxx.xxx 未訂閱
dear william : 我把程式改成以下這樣,compiler無誤,但是thread卻無法執行了,不知是爲什麼?? unit Unit2; interface uses Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF}, DB, ADODB, DBTables,Gauges,StdCtrls,Forms,SysUtils,ComCtrls; type TMoveData = class(TThread) private Gauge:TGauge; ADOStoredProc1: TADOStoredProc; ADOQuery1: TADOQuery; Table1:TTable; StartTime,Time1:TDateTime; iThread,DesTable :string; StatusBar:TStatusBar; protected procedure Execute; override; procedure GiveAnswer; // 告訴主程式Query已完成 procedure LstRefresh; public OkString:string; // 用來宣告動作完成用 FTotal:Integer; constructor Create(Source:TADOConnection; i_agym:String); // destructor Destroy; override; end; implementation uses Unit1; constructor TMoveData.Create(Source:TADOConnection;i_agym:String); begin iThread:=i_agym; StartTime := Now; //copy file CopyFile(Pchar('D:\khmfdown\source\khmfma.DBF'), PChar('D:\khmfdown\thisweek\khmfma' iThread '.DBF'),False); CopyFile(Pchar('D:\khmfdown\source\khmfag.DBF'), PChar('D:\khmfdown\thisweek\khmfag' iThread '.DBF'),False); CopyFile(Pchar('D:\khmfdown\source\khmfhe.DBF'), PChar('D:\khmfdown\thisweek\khmfhe' iThread '.DBF'),False); CopyFile(Pchar('D:\khmfdown\source\khmfri.DBF'), PChar('D:\khmfdown\thisweek\dbf\khmfri' iThread '.DBF'),False); CopyFile(Pchar('D:\khmfdown\source\khmfad.DBF'), PChar('D:\khmfdown\thisweek\dbf\khmfad' iThread '.DBF'),False); CopyFile(Pchar('D:\khmfdown\source\khmftr.DBF'), PChar('D:\khmfdown\thisweek\khmftr' iThread '.DBF'),False); CopyFile(Pchar('D:\khmfdown\source\khmflo.DBF'), PChar('D:\khmfdown\thisweek\khmflo' iThread '.DBF'),False); //----------------------end copty file // ADOStoredProc1:=TADOStoredProc.Create(Application); ADOquery1 :=TADOQuery.Create(Application); ADOquery1.Connection:= Source; { ADOStoredProc1.Connection:= Source; ADOStoredProc1.ProcedureName :='P_KHMFDOWN'; ADOStoredProc1.Parameters.AddParameter.Name :='i_agym'; ADOStoredProc1.Parameters.ParamByName('i_agym').value:=iThread; } table1:=TTable.Create(Application); Table1.TableName :='D:\khmfdown\thisweek\khmfma' iThread '.DBF'; ADOquery1.SQL.Clear; ADOquery1.SQL.Add ('truncate table ag.tb_main' iThread '@dev2 drop storage'); ADOquery1.ExecSQL ; inherited Create(false); end; procedure TMoveData.Execute; var i_sqrList :string; procedure AddRec(i_sqr :String ;i_table :string); var i,j:integer; begin { DesTable:=i_table; ADOquery1.SQL.Clear; ADOquery1.SQL.Add (i_sqr); ADOquery1.Open ; } table1.Open ; with ADOquery1 do begin table1.Append; for i:=0 to FieldCount-1 do table1.FieldByName(Fields.Fields[i].FieldName).Value:=Fields.Fields[i].Value; end; table1.Post ; Gauge.MaxValue:=ADOquery1.RecordCount; FTotal:=Gauge.MaxValue; Gauge.Progress:=0; end; begin Time1 := Now - StartTime; StatusBar:=MainForm.FindComponent('StatusBar' iThread) as TStatusBar; Gauge:=MainForm.FindComponent('Gauge' iThread) as TGauge; Gauge.Progress:=0; ADOquery1.SQL.Clear; { ADOquery1.SQL.Add('insert into ag.tb_main' iThread '@dev2(select /* Rule */ polno1,polno2,bid,bname,bsex,bborndt,bage, '); ADOquery1.SQL.Add('aid,aname,sex,aborndt,age,job,honydt,lab1,lab2, '); ADOquery1.SQL.Add('lab3,acym,agym,agdt,poldt,perd,bsf,subbpm,disgrp, '); ADOquery1.SQL.Add('disbpm,bpm,bpmtot,pay,paytype,ara,arazip,paytime, '); ADOquery1.SQL.Add('paydt,nextdt,style,excover,clcod,polsele,adjcod, '); ADOquery1.SQL.Add('grpno,no80m,spno,scry,autcod,unpcod,tracod,fovcod, '); ADOquery1.SQL.Add('txdt,expcod,sc,clmsc,ctend,prsc,anntime,lapsdt '); ADOquery1.SQL.Add('from qq.tab_khmf_main@dev2 '); ADOquery1.SQL.Add('where mod(round(poldt/100),100)=' iThread ')'); ADOquery1.ExecSQL ; } // i_sqrList:='select * from ag.tb_main' iThread '@dev2'; i_sqrList:='select * from ag.tb_main@dev2'; { ADOquery1.SQL.Add('select /* Rule */ b.polno1,b.polno2,b.agcod, '); ADOquery1.SQL.Add('b.agid,b.agname,b.divdept,b.divunit,b.divzone,b.divteam '); ADOquery1.SQL.Add('from ag.tb_main' iThread '@dev2 a,qq.tab_khmf_agid@dev2 b '); ADOquery1.SQL.Add('where a.polno1=b.polno1 and a.polno2=b.polno2 '); } ADOquery1.SQL.Clear; ADOquery1.SQL.Add (i_sqrList); ADOquery1.Open ; Gauge.MaxValue:= ADOquery1.RecordCount; FTotal:=Gauge.MaxValue; Gauge.Progress:=0; while not ADOquery1.eof do begin Synchronize(lstRefresh); AddRec(i_sqrList,DesTable); ADOquery1.Next ; end; ADOquery1.Free; Table1.Free; // i_sqrList.Free ; //Synchronize(GiveAnswer); // 宣告完成 end; procedure TMoveData.GiveAnswer; begin OKString:='OK' end; procedure TMoveData.LstRefresh; begin // if MainForm.bStoping then // Terminate; Gauge.Progress:=Gauge.Progress 1; StatusBar.Panels.Items[2].Text:=DesTable; StatusBar.Panels.Items[5].Text:=format('%d / %d ',[Gauge.Progress,FTotal]); Application.ProcessMessages; end; end. unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, ADODB, DBTables,StdCtrls, ComCtrls,Gauges; type TMainForm = class(TForm) Button1: TButton; BatchMove1: TBatchMove; ADOConnection1: TADOConnection; ADOStoredProc1: TADOStoredProc; Label1: TLabel; Edit1: TEdit; Label2: TLabel; StatusBar1: TStatusBar; StatusBar2: TStatusBar; StatusBar3: TStatusBar; StatusBar4: TStatusBar; StatusBar5: TStatusBar; procedure Button1Click(Sender: TObject); procedure StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; const Rect: TRect); private { Private declarations } public { Public declarations } end; var MainForm: TMainForm; implementation uses Unit2; {$R *.dfm} procedure TMainForm.Button1Click(Sender: TObject); var // Thread1,thread2 :TMoveData; Threads: array[0..11] of TMoveData; Time1:TDateTime; F:Double; i:integer; begin Time1:=now; { Thread1 := TMoveData.Create(ADOConnection1,'01'); while Thread1.OKString='' do // 還未執行完成時 begin f:=now()-Time1; f:=f * (24*60.0); label1.caption:=format('所花時間:%.2f分',[f]); Application.processmessages; end; Thread2 := TMoveData.Create(ADOConnection1,'02'); while Thread1.OKString='' do // 還未執行完成時 begin f:=now()-Time1; f:=f * (24*60.0); label2.caption:=format('所花時間:%.2f分',[f]); Application.processmessages; end; } for i := 1 to 1 do begin Threads[i] := TMoveData.Create(ADOConnection1,Format('%.2d',[i])); // TLabel(findcomponent('label' inttostr(i))).caption :=format('所花時間:%.2f分',[f]); Application.processmessages; end; for i := 1 to 1 do Threads[i].Free end; Procedure TMainForm.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; const Rect: TRect); var Gauge:TGauge; sGName:String; begin sGName:='Gauge' Format('%.2d',[StatusBar.Tag]); Gauge:=FindComponent(sGName) as TGauge; if Gauge=nil then begin Gauge:=TGauge.Create(Self); Gauge.Name:=sGName; Gauge.ForeColor:=clBlue; end; case Panel.ID of 4: with Gauge do begin // Tables Progress Component Parent:=StatusBar; Left:=Rect.Left; Top:=Rect.Top; Height:=Rect.Bottom-Rect.Top; Width:=Rect.Right-Rect.Left; end; end; end; end.
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-04-17 17:13:47 IP:147.8.xxx.xxx 未訂閱
1) You should call the inherited Create first...
constructor TMoveData.Create(Source:TADOConnection;i_agym:String);
begin
  inherited Create(false);
  {... all other }
end;
2) You need to wait for the thread to run, e.g.
Thread1 := TMoveData.Create(ADOConnection1,'01');
repeat
    { .... }
    Application.ProcessMessages;
    sleep(100);
until Thread1.Terminated;
Thread1.Free;
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-04-17 17:48:23 IP:61.218.xxx.xxx 未訂閱
Dear william : 我依照你的方法,但是還是沒反應ㄟ!!!
cyl
中階會員


發表:163
回覆:171
積分:66
註冊:2002-07-11

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-04-17 19:47:59 IP:61.218.xxx.xxx 未訂閱
因為之後的問題已偏離,原來我的主題,所以我結此案,另發問一個新問題
系統時間:2024-05-20 21:21:19
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!