如何同步執行Thread ?? |
答題得分者是:william
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
引言: 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 發送簡訊給我 |
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
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 發送簡訊給我 |
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].FreeThe 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 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
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 發送簡訊給我 |
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 發送簡訊給我 |
|
cyl
中階會員 發表:163 回覆:171 積分:66 註冊:2002-07-11 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |