Lob*_*uno 8 delphi multithreading
我有一个对象x,需要从几个(5+个线程)访问.对象的结构是
Tx = class
private
Fx: integer;
public
property x: integer read Fx read Fx;
etc;
Run Code Online (Sandbox Code Playgroud)
什么是更好(最优雅)的保护方式:
一个)
Tx = class
private
Fx: integer;
public
property x: integer read Fx read Fx;
public
constructor Create; <--- Create the criticalsection here
destructor Destroy; <--destroy it here
etc;
var
cs: TCriticalSection;
Obj: Tx;
function GetSafeObject(): Tx;
begin
CS.Enter;
try
Result:= Obj;
finally
CS.Leave;
Run Code Online (Sandbox Code Playgroud)
结束;
并始终将对象作为GetSafeObj()访问.x:= 3;
要么
Tx = class
private
Fx: integer;
FCS: TCriticalSection;
public
property x: integer read GerX read SetX;
public
constructor Create; <--- Create the criticalsection here
destructor Destroy; <--destroy it here
etc;
where
function Tx.Getx(): integer;
begin
CS.Enter;
try
Result:= Fx;
finally
CS.Leave;
end;
end;
Run Code Online (Sandbox Code Playgroud)
结束;
并始终正常访问该对象.我猜第一个选项更优雅,即使两种方法都能正常工作.你评论?
转到选项B,使关键部分在对象内部.如果该类的用户必须使用外部函数来安全地访问该实例,则不可避免地会有人不会和该房子一起倒下.
您还需要考虑您希望保护哪些操作语义免受多个并发读写操作的影响.如果在getter和setter中放置一个锁,则可以保证对象内部一致,但对象的用户可能会看到多线程工件.例如,如果线程A将10写入对象的属性,而线程B将50写入同一对象的该属性,则只有其中一个可以是最后一个.如果A恰好先行,则A将观察到他们给房子写了一张10,但是当他们再次读回来时,他们看到B的50在那里读到了A的写后读写间隙.
另请注意,您并不需要锁来保护单个整数字段.对齐指针大小的整数写入是当今几乎所有硬件系统上的原子操作.你肯定需要一个锁来保护多块数据,比如结构或多步操作,比如同时更改两个相关字段.
如果有任何方法可以重新设计您的设计以使这些对象在线程上的特定操作中是本地的,那么就这样做.制作本地数据副本可能会略微增加内存占用,但它可以大大简化多线程代码,并且比在整个应用程序中留下互斥锁地雷运行得更快.寻找其他简化假设 - 如果您可以设置系统以使对象在多个线程可用时是不可变的,那么该对象根本不需要任何锁定保护.只读数据适合跨线程共享.非常非常棒.