gpt4 book ai didi

multithreading - 通用线程安全属性

转载 作者:行者123 更新时间:2023-12-03 14:40:00 25 4
gpt4 key购买 nike

我创建了这个“线程安全”通用属性,我可以在主线程和后台线程之间使用它。我之所以这样做是因为我厌倦了为所有属性和变量创建锁定对象。

TLockedProp<MyType> = class
private
FMyProp:MyType;
PropLock:TObject;
procedure SetMyProp(const Value: MyType);
function GetMyProp: MyType;
published
property Value:MyType read GetMyProp write SetMyProp;
public
Constructor Create;
Destructor Destroy;override;
end;

{ TLockedProp<MyType> }

constructor TLockedProp<MyType>.Create;
begin
inherited;
PropLock:=TObject.create
end;

destructor TLockedProp<MyType>.Destroy;
begin
PropLock.Free;
inherited;
end;

function TLockedProp<MyType>.GetMyProp: MyType;
begin
TMonitor.Enter(PropLock);
result := FMyProp;
TMonitor.Exit(PropLock);
end;

procedure TLockedProp<MyType>.SetMyProp(const Value: MyType);
begin
TMonitor.Enter(PropLock);
FMyProp := Value;
TMonitor.Exit(PropLock);
end;

有什么我忽略的问题吗?这是使用这个属性类的一些代码。告诉我你的想法。

TBgThread=class(TThread)
private
FPaused: TLockedProp<boolean>;
FCount:TLockedProp<integer>;

procedure ChangeCount(pPlusMin:integer);
function GetPaused:boolean;
function GetCount:integer;
public
constructor Create;
destructor Destroy;override;
{Toggle Pause}
procedure PausePlay;
protected
procedure Execute;override;
published
Property Paused:boolean read GetPaused;
Property Count:integer read GetCount;
end;
constructor TBgThread.Create();
begin
inherited Create(true);;
FPaused:=TLockedProp<boolean>.create;
FPaused.Value:=false;
FCount:=TLockedProp<integer>.create;
FCount.Value:=0;
end;
destructor TBgThread.Destroy;
begin
FPaused.Free;
FCount.free;
inherited;
end;
procedure TBgThread.Execute;
begin
inherited;
Repeat
if not Paused then begin
Try
//do something
finally
ChangeCount(+1);
end;
end else
Sleep(90);
Until Terminated;
end;

function TBgThread.GetCount: integer;
begin
Result:=FCount.Value;
end;

procedure TBgThread.ChangeCount(pPlusMin: integer);
begin
FCount.Value:=FCount.Value+pPlusMin;
end;

function TBgThread.GetPaused: boolean;
begin
result := FPaused.Value;
end;

procedure TBgThread.PausePlay;
begin
FPaused.Value:=not FPaused.Value;
end;

最佳答案

您的代码很好,并且会序列化对该属性的读/写访问。我要说的唯一评论是您不需要创建单独的锁对象。您可以删除 PropLock 并锁定 Self

我的代码库中有一个几乎相同的类。唯一的区别是:

  1. 我使用临界区而不是 TMonitor,因为我仍然不信任 TMonitor。早期版本存在许多错误,这削弱了我的信心。但是,我怀疑 TMonitor 代码现在很可能是正确的。所以我认为你没有理由改变。
  2. 我将 try/finally 与锁定和解锁的代码一起使用。这对我来说可能有点悲观,因为很难看出如何有效地从 getter 和 setter 方法中的异常中恢复。我想是习惯的力量。

FWIW,我的类(class)版本如下所示:

type
TThreadsafe<T> = class
private
FLock: TCriticalSection;
FValue: T;
function GetValue: T;
procedure SetValue(const NewValue: T);
public
constructor Create;
destructor Destroy; override;
property Value: T read GetValue write SetValue;
end;

{ TThreadsafe<T> }

constructor TThreadsafe<T>.Create;
begin
inherited;
FLock := TCriticalSection.Create;
end;

destructor TThreadsafe<T>.Destroy;
begin
FLock.Free;
inherited;
end;

function TThreadsafe<T>.GetValue: T;
begin
FLock.Acquire;
Try
Result := FValue;
Finally
FLock.Release;
End;
end;

procedure TThreadsafe<T>.SetValue(const NewValue: T);
begin
FLock.Acquire;
Try
FValue := NewValue;
Finally
FLock.Release;
End;
end;

我想编写这个类实际上只有一种方法!

关于multithreading - 通用线程安全属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19703274/

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