gpt4 book ai didi

multithreading - delphi中的线程安全

转载 作者:行者123 更新时间:2023-12-03 14:56:52 24 4
gpt4 key购买 nike

我必须修改和更改线程中的一些可视组件,正如您所知,这样做并不安全。

我的问题是如何编写完全线程安全的代码?有可能吗?如果是的话你能给我一个简单的例子吗?

我的代码不是线程安全的:

type
tMyWorkerThread = class(TThread)
public
procedure Execute; override;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure tMyWorkerThread.Execute;
begin
//codes
//working with visual components
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TMyWorkerThread.Create(false);
end;

谢谢。

最佳答案

在 Delphi 中编写线程安全代码涉及到在任何其他语言中都会有的基本注意,这意味着处理竞争条件。当不同的线程访问相同的数据时,就会发生竞争条件。处理这个问题的一个好方法是声明一个 TCriticalSection 实例并将危险代码包装在其中。

下面的代码显示了属性的 getter 和 setter,根据假设,该属性具有竞争条件。

constructor TMyThread.Create;
begin
CriticalX := TCriticalSection.Create;
end;

destructor TMyThread.Destroy; override;
begin
FreeAndNil(CriticalX);
end;

function TMyThread.GetX: string;
begin
CriticalX.Enter;
try
Result := FX;
finally
CriticalX.Leave;
end;
end;

procedure TMyThread.SetX(const value: string);
begin
CriticalX.Enter;
try
FX := Value;
finally
CriticalX.Leave;
end;
end;

请注意使用 TCriticalSection (CriticalX) 的单个实例来序列化对数据成员 FX 的访问。

但是,使用 Delphi 您还有一个额外的考虑! VCL 不是线程安全的,因此为了避免 VCL 竞争条件,任何导致屏幕更改的操作都必须在主线程中运行。您可以通过在 Synchronize 方法中调用此类代码来实现这一点。考虑到上面的类,你应该这样做:

procedure TMyThread.ShowX;
begin
Synchronize(SyncShowX);
end;

procedure TMyThread.SyncShowX;
begin
ShowMessage(IntToStr(FX));
end;

如果您有 Delphi 2010 或更高版本,则有一种更简单的方法可以使用匿名方法:

procedure TMyThread.ShowX;
begin
Synchronize(procedure begin
ShowMessage(IntToStr(FX));
end);
end;

希望这会有所帮助!

关于multithreading - delphi中的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17705197/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com