I would like to know if it's possible to have this situation:
1) have a master thread with some variables.
2) this thread would have to create 2 sub-threads and this threads should be able to read the variables of the master thread.
3) I would like to create different master threads (with the sub-threads).
Is this even possible?
I tried this so far, but it does not work (Check "procedure 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.
Yes, it's possible to share variables among multiple threads. It's nearly automatic. If a variable's scope allows it to be referenced, then it will be accessible by whatever thread executes the code.
In the code provided, none of the threads have any way of referring to each other. In particular, the subthread has no reference to any instance of TMainThread
, and so it won't be able to access the TestVar1
member of any such thread.
It is not correct to let the SubThread inherit from the MainThread and then expect to get the test value.
I think it is much better to let the SubThread hold a reference to your Main Thread, and then you end up with this:
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.