作者:于华
在编写多线程应用
程序时,最重要的是控制好线程间的同步资源访问,以保证线程的安全运行。Win 32 API提供了一组同步对象,如:信号灯(Semaphore)、互斥(Mutex)、临界区(CriticalSection)和事件(Event)等,用来解决这个
问题。
Delphi分别将事件对象和临界区对象封装为Tevent对象和TcritialSection对象,使得这两个对象的使用简单且方便。但是如果在Delphi
程序中要使用信号灯或互斥等对象就必须借助于复杂的Win32 API函数,这对那些不熟悉Win32 API函数的编程人员来说很不方便。因此,笔者用Delphi构造了两个类,对信号灯和互斥对象进行了封装(分别为TSemaphore和TMutex),希望对广大Delphi编程人员有所帮助。
一、类的构造
我们先对Win32 API的信号灯对象和互斥对象进行抽象,构造一个父类THandleObjectEx,然后由这个父类派生出两个子类Tsemphore和Tmutex。
类的源代码如下:
unit SyncobjsEx;
interface
uses Windows,Messages,SysUtils,Classes,Syncobjs;
type
THandleObjectEx = class(THandleObject)
// THandleObjectEx为互斥类和信号灯类的父类
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)//互斥类
public
constructor Create(MutexAttributes: PSecurityAttributes; InitialOwner: Boolean;const Name:string);
procedure Release; override;
end;
TSemaphore = class(THandleObjectEx)
//信号灯类
public
constructor Create(SemaphoreAttributes: PSecurityAttributes;InitialCount:Integer;MaximumCount: integer; const Name: string);
procedure Release(ReleaseCount: Integer=1;PreviousCount:Pointer=nil);overload;
end;
implementation
{ THandleObjectEx }//父类的实现
destructor THandleObjectEx.Destroy;
begin
Windows.CloseHandle(FHandle);
inherited Destroy;
end;
procedure THandleObjectEx.Release;
begin
end;
function THandleObjectEx.WaitFor(Timeout: DWORD): TWaitResult;
//等待函数,参数为等待时间
begin
case WaitForSingleObject(Handle, Timeout) of
WAIT_ABANDONED: Result := wrAbandoned;
//无信号
WAIT_OBJECT_0: Result := wrSignaled;
//有信号
WAIT_TIMEOUT: Result := wrTimeout;//超时
WAIT_FAILED://失败
begin
Result := wrError;
FLastError := GetLastError;
end;
else
Result := wrError;
end;
end;
{ TSemaphore }//信号灯类的实现
constructor TSemaphore.Create(SemaphoreAttributes: PSecurityAttributes;
InitialCount, MaximumCount: integer; const Name: string);//信号灯类的构造函数
begin
FHandle := CreateSemaphore
(SemaphoreAttributes,InitialCount,
MaximumCount,PChar(Name));
//四个参数分别为:安全属性、初始信号灯计数、最大信号灯计数、信号灯名字
end;
procedure TSemaphore.Release(ReleaseCount: Integer=1; PreviousCount: Pointer=nil);
//信号灯类的Release方法,每执行一次按指定量增加信号灯计数