我有一个线程类,里面有一个数组变量(在线程内定义的),在线程create的初始化数组,在exectue里赋值
我实例化这个线程(两个以上实例)后,发现这个数组变量的值混乱了,数组里有赋值的,中间有为零的(初始化状态)!如果只运行一个实例,则数组都大于零。我看书上说,线程的局部变量是跟随实例的,在我这里怎么变成公共变量了?????
为什么?怎么解决?
我实例化这个线程(两个以上实例)后,发现这个数组变量的值混乱了,数组里有赋值的,中间有为零的(初始化状态)!如果只运行一个实例,则数组都大于零。我看书上说,线程的局部变量是跟随实例的,在我这里怎么变成公共变量了?????
为什么?怎么解决?
解决方案 »
- FreeCommunication 版本 3.6 已经出来了!
- 各位,请教用delphi编写的COM组件在网页中调用出现不支持此接口
- 大虾们有没有可以修改Delphi可执行文件的工具?
- 關于數據庫批量操作與progressbar的結合使用問題
- 菜鸟求助:关于修改表名,高手一句话解决的问题
- 今天开始学delphi,散分(前20位)
- 精典问题:我知道了某线程的ID号,如何调用API来把该线程删除(杀掉)?API名称是什么?
- 请问,在Paradox表中,有关日期型字段记录如何查询?
- 查询后的结果如何存入到EXCEL文件
- ClientDataSet+DBGrideh:注脚设置合计,往右边拉动滚动条很卡啊!
- D7下可以的代码XE2下无效
- 如果查看Delphi 的DLL内的方法,或如何反编译这个DLL,高手进来。
估计你没完全搞清楚 不好乱用
Ta = class(TThread)
arr: array[0..1] of Byte;
constructor Create; reintroduce;
procedure Execute; override;
end;constructor Ta.Create;
begin
arr[0]:=0;arr[1]:=0;
inherited Create(False)
end;
procedure Ta.Execute;
begin
FreeOnTerminate := True;
while not Terminated do
begin
arr[0]:=1;arr[1]:=2;
OutputDebugString(PChar(format('thread%d: %d,%d', [ThreadID, arr[0],arr[1]])));
Sleep(1000);
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
Ta.Create;
Ta.Create;
end;
Windows, Messages,SysUtils,Forms,ADODB,DB,Dialogs,RzDBEdit,popForm,DBGridEh,DBGrids,
ComObj,StdCtrls,Graphics,Classes, StrUtils, Registry, IniFiles, RzDBGrid, Math, Controls, ComCtrls,ExtCtrls,DateUtils;type
SendArr = Array[0..7] of byte;
RevArr = Array of byte;
PRevArr = ^RevArr;
TWYCSThrd = class(TThread)
private
{ Private declarations }
TPort: longint;
DevType,DevTypeName: String;
qry1,qry2,qry3,qry4 : TADOQuery;
MonitJG : Integer;
CanTerminated : boolean;
jzfieldname,jzdsdata,jzbj,arcsdm : array[0..80] of string;//数据错乱的数组 protected
procedure Execute; override;
function datajx(rev: array of byte) : boolean;
procedure savedata;
public
constructor Create(Suspended: Boolean; Port: Longint; SBLXDM: String; smjg : Integer);
destructor Destroy; override;
function getCanTerminated : boolean;
end;implementation
uses PComm,dataModule,public_unit;var
senddata:SendArr;
revdata : RevArr;
prev : PRevArr;
CS : TRTLcriticalsection;
OldMonth : Integer;
tablename : String;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure TWYCSThrd.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ TWYCSThrd }constructor TWYCSThrd.Create(Suspended: Boolean; Port: Integer;
SBLXDM: String; smjg : Integer);
var
i : integer;
sdate : String;
begin
inherited Create(Suspended);
FreeOnTerminate := True; TPort := Port;
DevType := SBLXDM;
DevTypeName := DevName;
MonitJG := smjg;
DateTimeToString(sdate, 'YYYYMM', now());
OldMonth := StrToInt(sdate);
sbdm := '';
fieldnum := 0;
dcfloop := 0;
loopednum := 1;
DCLoopNum := 1; looped := true;
赋初值
for i:= 0 to 79 do begin
jzfieldname[i]:= '';
jzdsdata[i] := '';
jzbj[i] := '';
arcsdm[i] := '';
end; getDCNUM;
tablename :=getTableNameH('BWYDdata');
if not getTableHExit(tablename) then
CreateTableH(tablename);
end;
function TWYCSThrd.datajx(rev: array of byte): boolean;
var
sqlstr,fieldname : string;
dw,bjz : string;
jxkz,gsdm : Integer;
bl ,calResult : double;
i,n : integer;
bitarr:array of integer;
xsz,xsj : string;
bjkz : Integer;
intarr : array of Integer;
sx,xx : double;//报警值上下线
begin try
qry2 := TADOQuery.Create(Application.Owner);
qry2.Connection := frmDataModule.WYConn; setlength(bitarr, regDataNum);
setlength(intarr, regDataNum*2);
dw := '';
if(rev[1]=1) or (rev[1]=2) then
begin
n := 0;
for i:= 0 to regDataNum-1 do begin
bitarr[i] := (rev[3+n] AND (1 shl (i-n*8))) shr (i-n*8);
if (i>0) and (((i+1) mod 8)=0) then
n:= n+1;
end;
end
else if(rev[1]=3) or (rev[1]=4) then
begin
n := 0;
for i:= 0 to regDataNum-1 do begin
intarr[i] := rev[3+i*2]*256+ rev[4+i*2];
end; end;
sqlstr := 'select * from WDYLCSJXB where mldm='+quotedstr(mldm);
with qry2 do begin
close;
SQL.Clear;
SQL.Add(sqlstr);
open;
end;
i := 0;
n := 0;
while not qry2.eof do begin
jxkz := qry2.FieldByname('jxkz').AsInteger;
if ( jxkz=0) then
begin
i:= i+1;
qry2.Next;
continue;
end
else begin //30
jxkz := qry2.FieldByname('jxkz').AsInteger;
gsdm := qry2.FieldByName('gsdm').AsInteger;
if(not qry2.FieldByName('dw').IsNull) then
dw := qry2.FieldByName('dw').AsString;
bl := qry2.FieldByName('bl').AsFloat;
fieldname := qry2.FieldByName('FieldName').AsString; if qry2.FieldByname('bjkz').AsBoolean = true then
bjkz := 1
else
bjkz := 0;
bjz := qry2.FieldByname('bjz').AsString;
if ((rev[1]=3) or (rev[1]=4)) and ( jxkz=1) then begin//15
jzfieldname[fieldnum] := fieldname;
if gsdm=5 then begin
calResult := calcFunction(intarr[i],0,0,0,qry2);
jzdsdata[fieldnum]:= Floattostr(calResult)+dw;
end;
if bjkz=1 then begin //17
if pos('-',bjz)>0 then begin
sx := strToFloat(copy(bjz,0,pos('-',bjz)-1));
xx := StrtoFloat(copy(bjz,pos('-',bjz)+1,length(bjz)-pos('-',bjz)));
if (calResult>=xx) or (calResult<=sx) then
jzbj[fieldnum] := '报警'
else
jzbj[fieldnum] := '正常';
end
else begin
if (calResult=strtoint(bjz)) then
jzbj[fieldnum] := '报警'
else
jzbj[fieldnum] := '正常'; end; end; //17 fieldnum := fieldnum+1;
i:= i+1;
end; //15
qry2.Next;
end; //30
end;// end while if Jugeloopover then begin
savedata;
for i:= 0 to 79 do begin
jzbj[i] := '';
end;
fieldnum := 0;
loopednum := 1;
end;
result:= true;
finally
qry2.Close;
qry2.Free;
qry2 := nil;
end;
end;destructor TWYCSThrd.Destroy;
begin
sio_close(TPort);
inherited;
end;procedure TWYCSThrd.Execute;
var
sqlstr : string;
datalenth,ret,jgsj : Integer;
startAdd : Integer;
olddate,newdate : TDateTime;
begin
{ Place thread code here }
try
initializeCriticalsection(CS); //增加 临界区初始化
qry1 := TADOQuery.Create(Application.Owner);
qry1.Connection := frmDataModule.WYConn;
olddate := now();
CanTerminated := true;
while not Terminated do begin
CanTerminated := true;
if looped then begin
looped := false;
WYrefresh := false;
CanTerminated := false;
sqlstr := 'select * from FunctionInfo where mldm like '+quotedstr(DevType+'%');
with qry1 do begin
close;
SQL.Clear;
SQL.Add(sqlstr);
open;
end;
while not qry1.Eof do begin
mldm := qry1.FieldByname('mldm').AsString;
senddata[0] := qry1.FieldByname('sbid').AsInteger;
senddata[1] := qry1.FieldByname('Funct').AsInteger; regDataNum := qry1.FieldByName('DataLenth').AsInteger;
startAdd := qry1.FieldByName('startAdd').AsInteger;
ret := write(senddata,startAdd,regDataNum);
if(ret=8) then begin
sleep(40);
getRevinfo(senddata[1],qry1.FieldByName('DataLenth').AsInteger);
ret := read(revDataLength+5,@revdata);
if(ret = 1) then
begin
prev := @revdata;
datajx(prev^);
end;
end;
qry1.Next;
end;
qry1.Close;
CanTerminated := true; end
else if looped=false then
CanTerminated := true;
newdate := now();
jgsj := SecondsBetween(newdate,olddate);
if(jgsj>=MonitJG) then begin
try
SetprocessWorkingSetSize(GetCurrentProcess,$FFFFFFFF,$FFFFFFFF);
finally
application.ProcessMessages ;
end;
looped := true;
olddate := now;
end;
CanTerminated := true;
application.ProcessMessages ;
sleep(50); end;
finally
sio_close(TPort);
qry1.Free;
qry1 := nil;
Deletecriticalsection(cs); //增加 临界区初始化
end;
end;function TWYCSThrd.getCanTerminated: boolean;
begin
if CanTerminated then
result := true
else
result := false;
end;procedure TWYCSThrd.savedata; // lst修改 20120401
var
i,newMonth : Integer;
sqlstr : string;
sdate : string;
begin
try
//对 最新月份赋值
DateTimeToString(sdate, 'YYYYMM', now());
newMonth := StrToInt(sdate);
qry4 := TADOQuery.Create(Application.Owner);
qry4.Connection := frmDataModule.WYConn;
tablename :=getTableNameH('BWYDdata');
// 跨月时,添加表 if(newMonth>OldMonth) then begin //11111
//锁定操作,使线程同步
EnterCriticalsection(cs);
if not getTableHExit(tablename) then
CreateTableH(tablename);
OldMonth := NewMonth;
LeaveCriticalsection(cs);
end; ///1111
//可以完全拷贝 111--111区间 sqlstr := 'select * from '+tablename+' where id=(select max(id) from '+tablename+')';
with qry4 do begin
close;
sql.Clear;
sql.Add(sqlstr);
open;
end; qry4.Append;
qry4.Edit;
qry4.FieldByName('sbdm').AsString := sbdm;
qry4.FieldByName('time_send').AsString := DateTimetoStr(now); for i:= 0 to fieldnum-1 do begin
// 这里报错,jzfieldname[i]为空,相互干扰了
qry4.FieldByName(jzfieldname[i]).AsString := jzdsdata[i];
qry4.FieldByName(jzfieldname[i]+'bj').AsString := jzbj[i];
end;
qry4.UpdateBatch;
WYrefresh := true;
finally
qry4.Close;
qry4.Free;
qry4 := nil;
end;
end;
end.
datajx(prev^);已经操作非局部代码了