簡體   English   中英

Delphi XE8-在線程之間共享變量

[英]Delphi XE8 - Share variables between threads

我想知道是否可能出現這種情況:

1)有一個帶有一些變量的主線程。

2)該線程將必須創建2個子線程,並且該線程應能夠讀取主線程的變量。

3)我想創建不同的主線程(與子線程)。

這有可能嗎?

到目前為止,我已經嘗試過了,但是它不起作用(檢查“ 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.

是的,可以在多個線程之間共享變量。 這幾乎是自動的。 如果變量的作用域允許引用它,那么執行該代碼的任何線程都可以訪問它。

在提供的代碼中,所有線程都沒有任何相互引用的方式。 特別是,該子線程沒有對TMainThread的任何實例的TMainThread ,因此它將無法訪問任何此類線程的TestVar1成員。

讓SubThread從MainThread繼承然后期望獲得測試值是不正確的。

我認為最好讓SubThread持有對您的Main Thread的引用,然后得出以下結論:

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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM