C
cgs1980
Unregistered / Unconfirmed
GUEST, unregistred user!
我有3个线程,线程 A 启动线程B, 并且线程A传递给线程B一个参数 ID(该ID赋值给线程B的 FID变量), 然后线程B执行时又会启动一个线程C, 线程B等待线程C执行完毕后,会对一个 ListView 进行更新,但此时发现线程B的 private 变量 FID 的值不等于线程A传递过来的值,我已经初步分析出原因,见下述,但有什么方法可以解决呢?示例代码如下所示:
AThread = class(TThread)
private
FListView1: TListView;
protected
procedure Execute;
override;
public
constructor Create();
end;
BThread = class(TThread)
private
FListView: TListView;
FID: Integer;
FTotalNumber: Integer;
procedure ThreadDone(Sender: TObject);
procedure UpdateInfo();
protected
procedure Execute;
override;
public
constructor Create(ListView: TListView;
ID: Integer);
end;
CThread = class(Thread)
protected
FStr: string;
FTotal: Integer ;
proceduredo
SomeThings();
protected
procedure Execute;
override;
public
property Total: Integerl read FTotal write FTotal;
constructor Create(Str: string);
end;
procedure AThread.Execute;
var
i, count: Integer;
begin
for i:=0 to 1do
begin
BThread.Create(FListView1, i);
end;
end;
constructor ThreadB.Create(ListView2: TListView;
ID: Integer);
begin
FListView := ListView2;
FID := ID;
FreeOnTerminate := True;
inherited Create(False);
end;
procedure BThread.Execute;
var
i, count: Integer;
str: String;
begin
Str := GetSomeThings();
with CThread.Create(Str)do
begin
OnTerminate := ThreadDone ;
end;
end;
procedure BThread.ThreadDone(Sender: TObject);
begin
if (Sender is CThread) then
begin
FTotalNumber := CThread(Sender).Total;
Synchronize( UpdateInfo );
end;
end;
procedure BThread.UpdateInfo();
var
index: Integer;
begin
[red]// 当线程CThread执行完毕后,BThread会执行这个UpdateInfo,但我多次跟踪测试,此时的 FID的取值与AThread传递的值不同,为什么呢?[/red]
FListView2.Items.Item[FID].Caption := IntToStr( FTotalNumber );
end;
procedure CThread.Execute;
begin
Total :=do
SomeOtherThings();
end;
当线程CThread执行完毕后,BThread会执行这个UpdateInfo函数,但我多次跟踪测试,执行此函数时, FID的取值与AThread传递的值不同,例如:线程A传递给线程B的 ID := 0,但当执行UpdateInfo函数时,FID 值发生了随机性的变化,多次测试,FID的值为 1868627968、58297等, 经过分析, 可能是由于我在线程C 的do
SomeOtherThings() 函数中加载了一个hash表(该表为全局变量),该表有几万条记录,当第一次执行 线程C时,会加载这个hash表,再次执行时,不会加载这个hash表(已经加载) , 那么可能存在一个原因是:当第一次加载hash表时,程序要分配一定的空间,此时将线程B的一些变量空间覆盖了。当hash表已经加载,再次启动线程B、线程C时,当执行 UpdateInfo函数时,FID的取值与AThread传递的值是相同的了,如果是因为hash表导致线程B的变量被覆盖,那么有什么方法可以避免这种情况呢?谢谢大家的指点。
AThread = class(TThread)
private
FListView1: TListView;
protected
procedure Execute;
override;
public
constructor Create();
end;
BThread = class(TThread)
private
FListView: TListView;
FID: Integer;
FTotalNumber: Integer;
procedure ThreadDone(Sender: TObject);
procedure UpdateInfo();
protected
procedure Execute;
override;
public
constructor Create(ListView: TListView;
ID: Integer);
end;
CThread = class(Thread)
protected
FStr: string;
FTotal: Integer ;
proceduredo
SomeThings();
protected
procedure Execute;
override;
public
property Total: Integerl read FTotal write FTotal;
constructor Create(Str: string);
end;
procedure AThread.Execute;
var
i, count: Integer;
begin
for i:=0 to 1do
begin
BThread.Create(FListView1, i);
end;
end;
constructor ThreadB.Create(ListView2: TListView;
ID: Integer);
begin
FListView := ListView2;
FID := ID;
FreeOnTerminate := True;
inherited Create(False);
end;
procedure BThread.Execute;
var
i, count: Integer;
str: String;
begin
Str := GetSomeThings();
with CThread.Create(Str)do
begin
OnTerminate := ThreadDone ;
end;
end;
procedure BThread.ThreadDone(Sender: TObject);
begin
if (Sender is CThread) then
begin
FTotalNumber := CThread(Sender).Total;
Synchronize( UpdateInfo );
end;
end;
procedure BThread.UpdateInfo();
var
index: Integer;
begin
[red]// 当线程CThread执行完毕后,BThread会执行这个UpdateInfo,但我多次跟踪测试,此时的 FID的取值与AThread传递的值不同,为什么呢?[/red]
FListView2.Items.Item[FID].Caption := IntToStr( FTotalNumber );
end;
procedure CThread.Execute;
begin
Total :=do
SomeOtherThings();
end;
当线程CThread执行完毕后,BThread会执行这个UpdateInfo函数,但我多次跟踪测试,执行此函数时, FID的取值与AThread传递的值不同,例如:线程A传递给线程B的 ID := 0,但当执行UpdateInfo函数时,FID 值发生了随机性的变化,多次测试,FID的值为 1868627968、58297等, 经过分析, 可能是由于我在线程C 的do
SomeOtherThings() 函数中加载了一个hash表(该表为全局变量),该表有几万条记录,当第一次执行 线程C时,会加载这个hash表,再次执行时,不会加载这个hash表(已经加载) , 那么可能存在一个原因是:当第一次加载hash表时,程序要分配一定的空间,此时将线程B的一些变量空间覆盖了。当hash表已经加载,再次启动线程B、线程C时,当执行 UpdateInfo函数时,FID的取值与AThread传递的值是相同的了,如果是因为hash表导致线程B的变量被覆盖,那么有什么方法可以避免这种情况呢?谢谢大家的指点。