我想知道是否可能出现这种情况:
1)有一个包含一些变量的主线程。
2)这个线程必须创建2个子线程,这个线程应该能够读取主线程的变量。
3)我想创建不同的主线程(使用子线程)。
这甚至可能吗?
我到目前为止尝试了这个,但它不起作用(检查"过程TSubThread.Execute;"):
unit uMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TMainThread = class(TThread)
private
protected
procedure Execute; override;
public
TestVar1: integer;
end;
TSubThread = class(TMainThread)
private
protected
procedure Execute; override;
public
end;
TfMain = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
function RunThread(trTestVar1: integer): TMainThread;
procedure ThreadTerminated(Sender: TObject);
function RunSubThread: TSubThread;
procedure SubThreadTerminated(Sender: TObject);
public
{ Public declarations }
end;
var
fMain: TfMain;
implementation
{$R *.dfm}
////////////////////////////////////////////////////////////////////////////////
// MAINTHREAD
////////////////////////////////////////////////////////////////////////////////
function TfMain.RunThread(trTestVar1: integer): TMainThread;
var CalcThread : TMainThread;
begin
CalcThread := TMainThread.Create(true);
CalcThread.TestVar1 := trTestVar1;
CalcThread.FreeOnTerminate := true;
CalcThread.OnTerminate := ThreadTerminated;
CalcThread.Start;
Result := CalcThread;
// Here I start the SUB-THREAD
RunSubThread;
end;
procedure TfMain.ThreadTerminated(Sender: TObject);
begin
//
end;
procedure TMainThread.Execute;
begin
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
// SUBTHREAD
////////////////////////////////////////////////////////////////////////////////
function TfMain.RunSubThread: TSubThread;
var SubThread : TSubThread;
begin
SubThread := TSubThread.Create(true);
SubThread.FreeOnTerminate := true;
SubThread.OnTerminate := SubThreadTerminated;
SubThread.Start;
Result := SubThread;
end;
procedure TfMain.SubThreadTerminated(Sender: TObject);
begin
//
end;
procedure TSubThread.Execute;
begin
inherited;
// Here the value of TestVar1 is always 0
end;
////////////////////////////////////////////////////////////////////////////////
// MAIN THREAD
////////////////////////////////////////////////////////////////////////////////
procedure TfMain.FormCreate(Sender: TObject);
begin
// I start the first "Main Thread"
RunThread(1);
// I start the second "Main Thread"
RunThread(2);
end;
end.
答案 0 :(得分:0)
是的,可以在多个线程之间共享变量。它几乎是自动的。如果变量的作用域允许它被引用,则任何执行代码的线程都可以访问它。
在提供的代码中,没有任何线程可以互相引用。特别是,子线程没有引用TMainThread
的任何实例,因此它无法访问任何此类线程的TestVar1
成员。
答案 1 :(得分:0)
让SubThread从MainThread继承然后期望得到测试值是不正确的。
我认为让SubThread保留对主线程的引用要好得多,然后你最终得到这个:
unit uMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TMainThread = class(TThread)
private
protected
procedure Execute; override;
public
TestVar1: integer;
end;
TSubThread = class(TThread)
private
FMainThread : TMainThread;
protected
procedure Execute; override;
public
end;
TfMain = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
function RunThread(trTestVar1: integer): TMainThread;
procedure ThreadTerminated(Sender: TObject);
function RunSubThread(MainThread : TMainThread): TSubThread;
procedure SubThreadTerminated(Sender: TObject);
public
{ Public declarations }
end;
var
fMain: TfMain;
implementation
{$R *.dfm}
////////////////////////////////////////////////////////////////////////////////
// MAINTHREAD
////////////////////////////////////////////////////////////////////////////////
function TfMain.RunThread(trTestVar1: integer): TMainThread;
var CalcThread : TMainThread;
begin
CalcThread := TMainThread.Create(true);
CalcThread.TestVar1 := trTestVar1;
CalcThread.FreeOnTerminate := true;
CalcThread.OnTerminate := ThreadTerminated;
CalcThread.Start;
Result := CalcThread;
// Here I start the SUB-THREAD
RunSubThread(CalcThread);
end;
procedure TfMain.ThreadTerminated(Sender: TObject);
begin
//
end;
procedure TMainThread.Execute;
begin
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
// SUBTHREAD
////////////////////////////////////////////////////////////////////////////////
function TfMain.RunSubThread(MainThread : TMainThread): TSubThread;
var SubThread : TSubThread;
begin
SubThread := TSubThread.Create(true);
SubThread.FreeOnTerminate := true;
SubThread.FMainThread := MainThread;
SubThread.OnTerminate := SubThreadTerminated;
SubThread.Start;
Result := SubThread;
end;
procedure TfMain.SubThreadTerminated(Sender: TObject);
begin
//
end;
procedure TSubThread.Execute;
var
VarCopy : Integer;
begin
inherited;
VarCopy := self.FMainThread.TestVar1;
// Here the value of TestVar1 is always 0
end;
////////////////////////////////////////////////////////////////////////////////
// MAIN THREAD
////////////////////////////////////////////////////////////////////////////////
procedure TfMain.FormCreate(Sender: TObject);
begin
// I start the first "Main Thread"
RunThread(1);
// I start the second "Main Thread"
RunThread(2);
end;
end.