转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Delphi中的线程类--之(3)         ★★★★

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

作者:闵涛 文章来源:闵涛的学习笔记 点击数:711 更新时间:2009/4/23 18:35:44

Delphi中的线程类

 

猛禽[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。这种情况你只能用API或RTL函数来创建线程。

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

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

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

 

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

 

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

 

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

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

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

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

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

(待续)


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台