multithreading - 全局实例线程中的私有字段是否安全
问题描述
我有以下形状的类
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;
解决方案
不,他们不是。
如果要在不同线程中使用相同的对象实例,则必须同步访问。
在 Windows 上只需使用临界区 (TRTLCriticalSection),在 posix os 上使用互斥锁 (pthread_mutex_t)
您始终可以选择将您的类设计为幂等的,因此您可以在每个线程中拥有它的实例并在其中使用它。
推荐阅读
- firebase - 如何保存用户数据
- python-3.x - 成对字符串和整数的切片列表
- php - isset($_GET['edit']) 之后的代码不起作用
- postgresql - 使用 psql 脚本将 jsonb 逗号分隔值转换为 json 对象
- scala - 从 Scala 中的元组列表创建数据框
- jquery - 我想从 API 中获取某些结果并将其显示到我的页面上
- react-native - 在 React Native Paper 中更改 TextInput 的文本颜色
- typescript - 设置 mat-option 值反应形式
- vue.js - 在整个 Vue 组件中使用变量?
- google-apps-script - 如何根据 Google AppMaker 中的表格字段填充下拉列表