【问题标题】:Reading thread's fields from synchronized event handler从同步事件处理程序中读取线程的字段
【发布时间】:2022-09-27 23:49:00
【问题描述】:

Synchronize 过程调用的事件处理程序中读取线程对象的字段是否安全?

例如:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;

type
  TMyThread = class(TThread)
  public
    Max : Integer;
    Position : Integer;
    OnPositionChanged : TNotifyEvent;
    procedure Execute(); override;
  end;

  TForm1 = class(TForm)
    ProgressBar1: TProgressBar;
    procedure FormCreate(Sender: TObject);
  private
    procedure MyOnPositionChanged(Sender : TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  Th : TMyThread;

procedure TMyThread.Execute();
begin
  while not Terminated do
  begin
    //doing stuffs
    Sleep(500);

    //position + 1
    Inc(Position);

    //event handler
    if(Assigned(OnPositionChanged)) then
    begin
      Synchronize(
        procedure()
        begin
          OnPositionChanged(Self);
        end
      );
    end;

    //check for reaching the max value
    if(Position = Max)
    then Terminate;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //preparing thread
  Th := TMyThread.Create(True);
  Th.FreeOnTerminate := True;
  Th.Max := ProgressBar1.Max;
  Th.Position := ProgressBar1.Position;
  Th.OnPositionChanged := MyOnPositionChanged;

  //starting thread
  Th.Start;
end;

procedure TForm1.MyOnPositionChanged(Sender : TObject);
begin
  //updating progressbar
  ProgressBar1.Position := (Sender as TMyThread).Position;
end;

end.

我想知道在另一个线程运行时从主线程读取线程的字段是否可能存在一些线程安全问题

  • 只要只有一个线程在写,并且整型变量是对齐的,那么多线程读取是安全的,在任何地方都没有同步。

标签: multithreading delphi thread-safety delphi-xe7


【解决方案1】:

是的,这通常是安全的。线程的Execute() 方法在Synchronize() 运行时被阻塞,因此在主线程使用字段时线程不会更新字段。

如果你碰巧有其他线程更新相同的字段没有Synchronize()'ing 访问它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多