知识大全 扩展Delphi的线程同步对象

Posted 扩展

篇首语:我不是天生的王者,但我骨子里流着不服输的血液。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 扩展Delphi的线程同步对象相关的知识,希望对你有一定的参考价值。

扩展Delphi的线程同步对象  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

   在编写多线程应用程序时 最重要的是控制好线程间的同步资源访问 以保证线程的安全运行 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 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): aitResult;

   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 THandleObjectEx Destroy;

  begin

  Windows CloseHandle(FHandle);

  inherited Destroy;

  end;

  procedure THandleObjectEx Release;

  begin

  end;

  function THandleObjectEx WaitFor(Timeout: DWORD): aitResult;

  //等待函数 参数为等待时间

  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 TSemaphore Create(SemaphoreAttributes: PSecurityAttributes;

  InitialCount MaximumCount: integer; const Name: string);//信号灯类的构造函数

  begin

  FHandle := CreateSemaphore

  (SemaphoreAttributes InitialCount MaximumCount PChar(Name));

  //四个参数分别为 安全属性 初始信号灯计数 最大信号灯计数 信号灯名字

  end;

  procedure TSemaphore Release(ReleaseCount: Integer= ; PreviousCount:Pointer=nil);

  //信号灯类的Release方法 每执行一次按指定量增加信号灯计数

  begin

  Windows ReleaseSemaphore(FHandle ReleaseCount PreviousCount);

  end;

   TMutex //互斥类的实现

  constructor TMutex Create(MutexAttributes: PSecurityAttributes;

  InitialOwner: Boolean; const Name: string);

  //互斥类的构造函数

  begin

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

  end;

  procedure TMutex Release;//互斥类的Release方法 用来释放对互斥对象的所有权

  begin

  Windows ReleaseMutex(FHandle);

  end;

  end;

  二 信号灯对象与互斥对象的使用    信号灯对象

  信号灯对象维持一个从 到指定最大值之间的数 在其计数大于 时是有信号的 而在其计数为 时是无信号的 信号灯对象可用来限制对共享资源进行访问的线程数量 例如应用程序可使用信号灯对象来限制它建立的窗口数量

  用类的Create方法来建立信号灯对象 在调用该方法时 可以指定对象的初始计数和最大计数 该方法有四个参数 依次为 安全属性 初始计数 最大计数和对象名字(以便别的进程的线程可打开指定名字的信号灯句柄) 如

  Semaphore := TSemaphore Create(nil );

  一般把信号灯的初始计数设置成最大值 每次当信号灯有信号并等待函数返回时 信号灯计数就会减 而通过调用对象的Release方法可按指定量增加信号灯的计数(默认为加 ) 计数值越小就表明访问共享资源的程序越多 如 Semaphore Release( nil); 其中第一个参数为增加的信号灯数量 第二个参数为执行该方法之前的信号灯数量   信号灯用法举例

  if wrSignaled = Semaphore WaitFor( ) then//若信号灯是有信号的

  begin

   //打开另一个窗口

  end

   Semaphore Release()

  在线程建立窗口之前 它使用WaitFor函数确定信号灯的当前计数是否允许建立新的窗口 等待时间设为 秒

   互斥对象

  Mutex对象的状态在它不被任何线程拥有时是有信号的 而当它被拥有时则是无信号的 Mutex对象很适合用来协调多个线程对共享资源的互斥访问(mutually exclusive) 例如 有几个线程共享对数据库的访问时 线程可以使用Mutex对象 一次只允许一个线程向数据库写入

  用类的Create方法建立Mutex 对象 在建立Mutex 时 可以为对象起个名字 这样其他进程中的线程可以打开指定名字的Mutex对象句柄 例如

  Mutex := TMutex Create(nil False );

  在完成对共享资源的访问后 可以调用Release方法来释放Mutex 以便让别的线程能访问共享资源 如果线程终止而不释放Mutex 则认为该Mutex被废弃

  互斥对象用法举例如下

  if wrSignaled = Mutex WaitFor( ) then//若获得互斥对象的拥有权

   begin

   try

   //往数据库写入

   finally

  Mutex Release;//释放对互斥对象的拥有权

   end;

   end;

cha138/Article/program/Delphi/201311/8521

相关参考

知识大全 多线程的批量线程同步解决方案

  多线程运行时有待处理线程?试试看下面介绍的这个批量线程同步方法吧  在一批线程处理程序中有时必须等到所有线程全部运行完后才能进行下一步任务处理可以采用如下方法解决创建一个锁对象该锁对象提供一个当前

知识大全 死锁

  由于线程可能进入堵塞状态而且由于对象可能拥有同步方法——除非同步锁定被解除否则线程不能访问那个对象——所以一个线程完全可能等候另一个对象而另一个对象又在等候下一个对象以此类推这个等候链最可怕的情形

知识大全 线程的同步-同步块

Java线程:线程的同步-同步块  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nbs

知识大全 多线程的批量线程同步处理方案

JAVA认证:多线程的批量线程同步处理方案  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  多线程

知识大全 Java的多线程-实现多线程及线程的同步

Java的多线程-实现多线程及线程的同步  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一.实现

知识大全 线程的同步与锁

Java线程:线程的同步与锁  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一同步问题提出  线

知识大全 浅谈Java多线程的同步问题

浅谈Java多线程的同步问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  多线程的同步依靠的是

知识大全 Java多线程同步具体实例讲解

Java多线程同步具体实例讲解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多线程同步

知识大全 java破解ip屏蔽+多线程同步拨号

  单线程破解ip屏蔽比较容易只要拨号就行了  多线程抓取数据也比较容易但是引入多线程之后拨号就容易出现问题  多线程抓取的时候这个拨号就比较麻烦一点因为多线程拨号  会出现第一个线程拨号的时候第二个

知识大全 Java多线程共享数据、同步、通信

Java多线程共享数据、同步、通信  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一线程共享数据