首页 > 解决方案 > 全局实例线程中的私有字段是否安全

问题描述

我有以下形状的类

TParser = class

private

  FFlag : boolean;
  FIntermediateValue : double;

  procedure F1(var aPartOfInput : string);
  procedure F2(var aSmallerPartOfInput : string) ;

public
  function Parse(const anInput : string): double;

end;

function TParser.Parse(const anInput : string) : double;
var
  aPartOfInput : string;
begin

  { Do some checks on the input and set FFlag to true/false.
    Set aPartOfInput to a piece of the input}
  f1(aPartOfInput);
  Result := FIntermediateValue;
end;

procedure TParser.F1(var aPartOfInput : string);
begin
  { Slice some more off the input.
    Set the FIntermediateValue }
  f2(aPartOfInput)
end;

procedure TParser.F2(var aSmallerPartOfInput : string);
begin
  { Depending on the input and FFlag, update FIntermediateValue }
end;

我们目前通过系统创建/销毁其中的一个 squillion(技术术语)。

我正在考虑创建一个实例并从每个地方调用它。

这个单一实例将从多个线程中调用。
使用私有字段是否意味着这不是线程安全的?

如果这不是线程安全的,我有哪些选择可以使它成为线程安全的?

编辑 - 选项

感谢大家的评论。

每个线程都有一个单独的实例

听起来不错,但由于代码的结构方式,实例需要对线程是“全局的”,没有办法(据我所知)将实例注入对象图中的位置它需要(目前,在需要的地方创建解析器的新实例)

threadvar
    TheParser : TParser;

似乎是给我这个的一种方式。当我们启动线程时创建实例并在离开时释放它。这有什么问题吗?

摆脱实例变量

如果我们重新设计解析器,使它成为一个函数而不是一个类的实例,并且所有的值都被传递,这会使它成为线程安全的吗?

interface

function Parse(const anInput : string): double;

implementation

function F2(var aSmallerPartOfInput : string; theFlag : boolean; theIntermediateValue : double) : double ;
begin
  { update theIntermediateValue based on flag and input }
  Result := theIntermediateValue;
end;

function F1(var aPartOfInput : string; theFlag : boolean) : double;
var
  anIntermediateValue : double;
begin
  { Slice some more off the input
    Set the FIntermediateValue }
  Result := f2(aPartOfInput, theFlag, anIntermediateValue)
end;

function Parse(const anInput : string) : double;
var
  aPartOfInput : string;
  aFlag : boolean;
begin

  { set aFlag
    set aPartOfInput to a piece of the input }
  Result := f1(aPartOfInput, aFlag);
end;

标签: multithreadingdelphi

解决方案


不,他们不是。

如果要在不同线程中使用相同的对象实例,则必须同步访问。

在 Windows 上只需使用临界区 (TRTLCriticalSection),在 posix os 上使用互斥锁 (pthread_mutex_t)

您始终可以选择将您的类设计为幂等的,因此您可以在每个线程中拥有它的实例并在其中使用它。


推荐阅读