Reputation: 581
I am working with threads and that's the reason I use mutexes for locking shared resources. The base usage of locking is to put resources within Lock/unlock block.
procedure RefreshData;
begin
DataLock;
GetData;
GetSettings;
CheckValues;
...
DataUnlock;
end;
Because there is always a pair Lock/Unlock I started thinking about simplified lock/unlock approach which would automatical unlock resources when not needed anymore.
So my idea was to introduce new procedure which would take as an input parameter a reference to precedure. This will give me ability to use anonymous method.
Code would be something like:
type TBaseProc = reference to procedure;
procedure TMyObject.LockMethod(AMeth: TBaseProc);
begin
DataLock;
try
AMeth;
finally
DataUnlock;
end;
end;
procedure TForm1.RefreshData;
begin
MyObject.LockMethod(
procedure
begin
GetData;
GetSettings;
CheckValues;
...
end;
);
end;
Has this approach any sense or is there better or even easier solution to this?
Thanks and regards.
Upvotes: 5
Views: 1343
Reputation: 4812
This approach is far from perfect because you have one lock per entire application, as I understood from your code. It is better when each independent data entity has its own lock. So you would have an abstract class like this:
type
TAbstractData = class
private
CriticalSection: TRtlCriticalSection
public
constructor Create;
procedure Lock;
procedure Unlock;
destructor Destroy; override;
end;
Then inherit other classes from this abstract class that implements locking.
constructor TAbstractData.Create;
begin
inherited Create;
InitializeCriticalSection(CriticalSection);
end;
procedure TAbstractData.Lock;
begin
EntercriticalSection(CriticalSection);
end;
procedure TAbstractData.Unlock;
begin
LeaveSection(CriticalSection);
end;
procedure TAbstractData.Destroy;
begin
DeleteCriticalSection(CriticalSection);
inherited Destroy;
end;
A CriticalSection
is the most efficient synchronization class implemented in Windows. It is virtually free - consumes almost no system resources unless there is thread contention, and does not invoke expensive context switch when just one thread uses the data.
After I have submitted the answer, I have found a good article on the Internet - http://blog.synopse.info/post/2016/01/09/Safe-locks-for-multi-thread-applications - the author recommends a similar approach.
Upvotes: 1