When writing multi-threaded applications, the most important thing is to control synchronized resource access between threads to ensure the safe operation of threads. Win 32 API provides a set of synchronization objects, such as Semaphore, Mutex, Critical Section, Event, etc., to solve this problem.
Delphi encapsulates event objects and critical section objects into Tevent objects and TcriticalSection objects respectively, making the use of these two objects simple and convenient. However, if you want to use objects such as semaphores or mutexes in a Delphi program, you must resort to complex Win32 API functions, which is very inconvenient for programmers who are not familiar with Win32 API functions. Therefore, the author used Delphi to construct two classes to encapsulate the semaphore and mutex objects (TSemaphore and TMutex respectively), hoping to be helpful to the majority of Delphi programmers.
1. Class structure
We first abstract the semaphore object and mutex object of the Win32 API, construct a parent class THandleObjectEx, and then derive two subclasses Tsemphore and Tmutex from this parent class.
The source code of the class is as follows:
unit SyncobjsEx;
interface
uses Windows,Messages,SysUtils,Classes,Syncobjs;
type
THandleObjectEx = class(THandleObject)
// THandleObjectEx is the parent class of the mutual exclusion class and the semaphore class
PRotected
FHandle: THandle;
FLastError: Integer;
public
destructor Destroy; override;
procedure Release;override;
function WaitFor(Timeout: DWord): TWaitResult;
property LastError:Integer read FLastError;
property Handle: THandle read FHandle;
end;
TMutex = class(THandleObjectEx)//Mutually exclusive class
public
constructor Create(MutexAttributes: PSecurityAttributes; InitialOwner: Boolean; const Name:string);
procedure Release; override;
end;
TSemaphore = class(THandleObjectEx)
//Signal light class
public
constructor Create(SemaphoreAttributes: PSecurityAttributes;InitialCount:Integer;MaximumCount: integer; const Name: string);
procedure Release(ReleaseCount: Integer=1;PreviousCount:Pointer=nil); overload;