Delphi中的线程类--之(3)

原创 2003年12月02日 22:00:00

Delphi中的线程类<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

猛禽[Mental Studio]

http://mental.mentsu.com

 

之三

说完构造函数,再来看析构函数:

destructor TThread.Destroy;

begin

  if (FThreadID <> 0) and not FFinished then

  begin

    Terminate;

    if FCreateSuspended then

      Resume;

    WaitFor;

  end;

  if FHandle <> 0 then CloseHandle(FHandle);

  inherited Destroy;

  FFatalException.Free;

  RemoveThread;

end;

在线程对象被释放前,首先要检查线程是否还在执行中,如果线程还在执行中(线程ID不为0,并且线程结束标志未设置),则调用Terminate过程结束线程。Terminate过程只是简单地设置线程类的Terminated标志,如下面的代码:

procedure TThread.Terminate;

begin

  FTerminated := True;

end;

所以线程仍然必须继续执行到正常结束后才行,而不是立即终止线程,这一点要注意。

在这里说一点题外话:很多人都问过我,如何才能“立即”终止线程(当然是指用TThread创建的线程)。结果当然是不行!终止线程的唯一办法就是让Execute方法执行完毕,所以一般来说,要让你的线程能够尽快终止,必须在Execute方法中在较短的时间内不断地检查Terminated标志,以便能及时地退出。这是设计线程代码的一个很重要的原则!

当然如果你一定要能“立即”退出线程,那么TThread类不是一个好的选择,因为如果用API强制终止线程的话,最终会导致TThread线程对象不能被正确释放,在对象析构时出现Access Violation。这种情况你只能用APIRTL函数来创建线程。

如果线程处于启动挂起状态,则将线程转入运行状态,然后调用WaitFor进行等待,其功能就是等待到线程结束后才继续向下执行。关于WaitFor的实现,将放到后面说明。

线程结束后,关闭线程Handle(正常线程创建的情况下Handle都是存在的),释放操作系统创建的线程对象。

然后调用TObject.Destroy释放本对象,并释放已经捕获的异常对象,最后调用RemoveThread减小进程的线程数。

 

其它关于Suspend/Resume及线程优先级设置等方面,不是本文的重点,不再赘述。下面要讨论的是本文的另两个重点:SynchronizeWaitFor

 

但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区。

 

事件(Event)与Delphi中的事件有所不同。从本质上说,Event其实相当于一个全局的布尔变量。它有两个赋值操作:SetReset,相当于把它设置为TrueFalse。而检查它的值是通过WaitFor操作进行。对应在Windows平台上,是三个API函数:SetEventResetEventWaitForSingleObject(实现WaitFor功能的API还有几个,这是最简单的一个)。

这三个都是原语,所以Event可以实现一般布尔变量不能实现的在多线程中的应用。SetReset的功能前面已经说过了,现在来说一下WaitFor的功能:

WaitFor的功能是检查Event的状态是否是Set状态(相当于True),如果是则立即返回,如果不是,则等待它变为Set状态,在等待期间,调用WaitFor的线程处于挂起状态。另外WaitFor有一个参数用于超时设置,如果此参数为0,则不等待,立即返回Event的状态,如果是INFINITE则无限等待,直到Set状态发生,若是一个有限的数值,则等待相应的毫秒数后返回Event的状态。

EventReset状态向Set状态转换时,唤醒其它由于WaitFor这个Event而挂起的线程,这就是它为什么叫Event的原因。所谓“事件”就是指“状态的转换”。通过Event可以在线程间传递这种“状态转换”信息。

当然用一个受保护(见下面的临界区介绍)的布尔变量也能实现类似的功能,只要用一个循环检查此布尔值的代码来代替WaitFor即可。从功能上说完全没有问题,但实际使用中就会发现,这样的等待会占用大量的CPU资源,降低系统性能,影响到别的线程的执行速度,所以是不经济的,有的时候甚至可能会有问题。所以不建议这样用。

(待续)

Delphi 多线程编程(3)

多线程程处理 1-1 多线程的基本概念 多线程带来如下好处:(自己阅读) 1)避免瓶颈; 2)并行操作; 3)提高效率; 在多线程中,通过优先级管理,可以使...
  • lailai186
  • lailai186
  • 2013年04月09日 08:32
  • 2416

线程之间的通信(thread signal)

线程通信的目的是为了能够让线程之间相互发送信号。另外,线程通信还能够使得线程等待其它线程的信号,比如,线程B可以等待线程A的信号,这个信号可以是线程A已经处理完成的信号。通过共享对象通信有一个简单的实...
  • suifeng3051
  • suifeng3051
  • 2016年07月08日 17:57
  • 2915

Delphi 多线程编程(1)

本文的内容取自万一博客,并重新加以整理,在此留存仅仅是方便自己学习和查阅。所有代码均亲自测试 delphi7下测试有效。图片均为自己制作。 多线程应该是编程工作者的基础技能, 但这个基础我从来没...
  • lailai186
  • lailai186
  • 2013年04月09日 07:55
  • 2583

DELPHI 线程类搜索全盘

  • 2011年05月17日 14:00
  • 246KB
  • 下载

Delphi中的线程类 - TThread详解

Delphi中的线程类 - TThread详解 日期:2010.12.07 | 分类:未分类 | 标签: Delphi 线程 TThread Delphi中有一个线程类TThr...
  • yangtao6888
  • yangtao6888
  • 2012年06月11日 17:52
  • 3639

Delphi 实现检测线程类TThread是否结束

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, F...
  • easyboot
  • easyboot
  • 2013年03月21日 10:48
  • 1143

[转]Delphi线程类

====================================================== 注:本文源代码点此下载 =============================...
  • javazhuanzai
  • javazhuanzai
  • 2012年01月16日 04:56
  • 135

Delphi中的线程类

 转贴于 华夏黑客同盟 http://www.77169.orgDelphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几...
  • mylovemoon2010
  • mylovemoon2010
  • 2011年02月01日 09:52
  • 407

Delphi中的线程类II

转自:http://blog.sina.com.cn/s/blog_494305f3010093pp.htmlCriticalSection临界区的应用但是在介绍这两个函数之前,需要先介绍另外两个线程...
  • god00
  • god00
  • 2011年07月21日 18:30
  • 265

Delphi中的线程类 - TThread详解

Delphi中的线程类 - TThread详解 2011年06月27日 星期一 20:28 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到...
  • youthon
  • youthon
  • 2011年08月26日 11:13
  • 1052
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi中的线程类--之(3)
举报原因:
原因补充:

(最多只允许输入30个字)