熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

擴展Delphi的線程同步對象

2013-11-11 21:06:35  來源: Delphi編程 
   在編寫多線程應用程序時最重要的是控制好線程間的同步資源訪問以保證線程的安全運行Win API提供了一組同步對象信號燈(Semaphore)互斥(Mutex)臨界區
(CriticalSection)和事件(Event)等用來解決這個問題

  Delphi分別將事件對象和臨界區對象封裝為Tevent對象和TcritialSection對象使得這兩個對象的使用簡單且方便但是如果在Delphi程序中要使用信號燈或互斥等對象就必須借助於復雜的Win API函數這對那些不熟悉Win API函數的編程人員來說很不方便因此筆者用Delphi構造了兩個類對信號燈和互斥對象進行了封裝(分別為TSemaphore和TMutex)希望對廣大Delphi編程人員有所幫助

  類的構造
  我們先對Win API的信號燈對象和互斥對象進行抽象構造一個父類THandleObjectEx然後由這個父類派生出兩個子類Tsemphore和Tmutex

  類的源代碼如下

  unit SyncobjsEx;

  interface

  uses WindowsMessagesSysUtilsClassesSyncobjs;

  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=;PreviousCount:Pointer=nil)

  overload;

  end;

  implementation

  { THandleObjectEx }//父類的實現

  destructor THandleObjectExDestroy;

  begin

  WindowsCloseHandle(FHandle);

  inherited Destroy;

  end;

  procedure THandleObjectExRelease;

  begin

  end;

  function THandleObjectExWaitFor(Timeout: DWORD): TWaitResult;

  //等待函數參數為等待時間

  begin

  case WaitForSingleObject(Handle Timeout) of

  WAIT_ABANDONED: Result := wrAbandoned;

  //無信號

  WAIT_OBJECT_: Result := wrSignaled;

  //有信號

  WAIT_TIMEOUT: Result := wrTimeout;//超時

  WAIT_FAILED://失敗

   begin

   Result := wrError;

   FLastError := GetLastError;

   end;

   else

   Result := wrError;

   end;

   end;

  { TSemaphore }//信號燈類的實現

  constructor TSemaphoreCreate(SemaphoreAttributes: PSecurityAttributes;

  InitialCount MaximumCount: integer; const Name: string);//信號燈類的構造函數

  begin

  FHandle := CreateSemaphore

  (SemaphoreAttributesInitialCount MaximumCountPChar(Name));

  //四個參數分別為安全屬性初始信號燈計數最大信號燈計數信號燈名字

  end;

  procedure TSemaphoreRelease(ReleaseCount: Integer=; PreviousCount:Pointer=nil);

  //信號燈類的Release方法每執行一次按指定量增加信號燈計數

  begin

  WindowsReleaseSemaphore(FHandle ReleaseCount PreviousCount);

  end;

  { TMutex }//互斥類的實現

  constructor TMutexCreate(MutexAttributes: PSecurityAttributes;

  InitialOwner: Boolean; const Name: string);

  //互斥類的構造函數

  begin

  FHandle := CreateMutex(MutexAttributes InitialOwner PChar(Name));

  end;

  procedure TMutexRelease;//互斥類的Release方法用來釋放對互斥對象的所有權

  begin

  WindowsReleaseMutex(FHandle);

  end;

  end;

  信號燈對象與互斥對象的使用

   信號燈對象

  信號燈對象維持一個從到指定最大值之間的數在其計數大於時是有信號的而在其計數為時是無信號的信號燈對象可用來限制對共享資源進行訪問的線程數量例如應用程序可使用信號燈對象來限制它建立的窗口數量

  用類的Create方法來建立信號燈對象在調用該方法時可以指定對象的初始計數和最大計數該方法有四個參數依次為安全屬性初始計數最大計數和對象名字(以便別的進程的線程可打開指定名字的信號燈句柄)

  Semaphore := TSemaphoreCreate(nil);

  一般把信號燈的初始計數設置成最大值每次當信號燈有信號並等待函數返回時信號燈計數就會減而通過調用對象的Release方法可按指定量增加信號燈的計數(默認為加計數值越小就表明訪問共享資源的程序越多SemaphoreRelease( nil);其中第一個參數為增加的信號燈數量第二個參數為執行該方法之前的信號燈數量

  信號燈用法舉例

  if wrSignaled = SemaphoreWaitFor() then//若信號燈是有信號的

  begin

   //打開另一個窗口

  end

   SemaphoreRelease()

  在線程建立窗口之前它使用WaitFor函數確定信號燈的當前計數是否允許建立新的窗口等待時間設為

   互斥對象

  Mutex對象的狀態在它不被任何線程擁有時是有信號的而當它被擁有時則是無信號的Mutex對象很適合用來協調多個線程對共享資源的互斥訪問(mutually exclusive)例如有幾個線程共享對數據庫的訪問時線程可以使用Mutex對象一次只允許一個線程向數據庫寫入

  用類的Create方法建立Mutex 對象在建立Mutex 時可以為對象起個名字這樣其他進程中的線程可以打開指定名字的Mutex對象句柄例如

  Mutex := TMutexCreate(nil False );

  在完成對共享資源的訪問後可以調用Release方法來釋放Mutex以便讓別的線程能訪問共享資源如果線程終止而不釋放Mutex則認為該Mutex被廢棄

  互斥對象用法舉例如下

  if wrSignaled = MutexWaitFor() then//若獲得互斥對象的擁有權

   begin

   try

   //往數據庫寫入

   finally

  MutexRelease;//釋放對互斥對象的擁有權

   end;

   end;

  上述類代碼在Windows Delphi 下調試通過


From:http://tw.wingwit.com/Article/program/Delphi/201311/8521.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.