说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

使用Delphi 4.0编写多线程

HTML文档下载 WORD文档下载 PDF文档下载
使用Delphi 4.0编写多线程

1.介绍

VCL提供几个对象以方便编写多线程应用。使用多线程可以避开一些性能的瓶颈。使用不同优先权的线程可以给重要的任务更多的CPU时间。在多处理器机器上,使用多个线程并将不同的线程放在不同的处理器上运行,将会提高应用的性能。当有相应的底层硬件时,NT操作系统支持真正的多线程,而即使底层硬件支持多处理器,95也只能模拟多线程的运行。

2.定义线程对象

对于大多数应用,可以使用线程对象来表示一个执行的线程。线程对象封装线程必需的应用,简化了多线程的编写。

注意:多线程对象并不允许泥控制线程的安全属性或栈的大小。如果需要控制这些,必须使用BeginThread函数。即使使用BeginThread,仍然能从一些线程同步的对象和在定位相差的方法中获取好处。

为了在应用中使用线程对象,首先必须产生一个TThread的继承对象。在file|new菜单中选择Thread Object创建。

新产生的Thread Object 包括一个框架代码,以下是一个名为TMyThread的线程:

unit Unit2;

interface

uses

Classes;

type

TMyThread = class(TThread)

private

{ Private declarations }

protected

procedure Execute; override;

end;

implementation

{ TMyThread }

procedure TMyThread.Execute;

begin

{ Place thread code here }

end;

end.

在自动产生的unit文件中,你应该:

l (可选)初始化线程

l 填写Execute方法,编写线程函数

l (可选)编写清除代码

3.初始化线程

如果你要为线程编写初始化代码,必须重载Create方法。在线程的声明中加入一个新的构造函数,并在它的实现中编写初始化代码。在这里你能够为线程设置一个缺省的优先级和当它执行完毕时,是否应该自动的释放。

3.1 设置一个缺省的优先级

优先级分为7级,如下表所示:

TpIdle The thread executes only when the system is idle. Windows won't

interrupt other threads to execute a thread with tpIdle priority.

TpLowest The thread's priority is two points below normal.

TpLower The thread's priority is one point below normal.

TpNormal The thread has normal priority.

TpHigher The thread's priority is one point above normal.

TpHighest The thread's priority is two points above normal.

TpTimeCritical The thread gets highest priority.

警告:一味地提高对CPU敏感的操作的线程的优先级会饿死其它线程。应该提高那些经常等待外部事件的线程的优先级。以下的代码表示一个低优先级的执行后台任务的线程,它在其它的时间内不会打扰应用的执行。

constructor TMyThread.Create(CreateSuspended: Boolean);

{

inheritedCreate(CreateSuspended);

Priority := tpIdle;

}

3.2 指明线程的释放

一般情况下,线程只会被执行一次,在这种情况下,特别方便让线程释放它自身,只要简单的将FreeOnTerminate特性置为true。如果需要多次运行,或同一个线程的多个实例,你可以缓存线程以提高性能,这时,将FreeOnTerminate特性置为false。

4.编写Execute方法

Execute方法是线程的函数。泥可以将它想象成一个由你的应用启动的程序,只是它共享了同样的进程空间。写线程函数稍微要注意一点是要确信没有写其他进程使用的内存,另外,你优可以使用共享内存在不同的线程之间通信,因为它们是在同一个进程空间中。

4.1 使用主VCL线程

当你使用从VCL继承过来的对象,他们的特性和方法并不能保证是线程安全的,即,访问特性货方法也许会执行一些使用一些没有被其他线程保护的内存。因此,为VCL对象的访问设了一个主VCL线程。这是处理应用程序中组件接收的所有的Windows消息的线程。 如果所有对象是在同一个线程中访问特性和方法,就不必担心会发生冲突。为了使用主VCL线程,产生一个分离的过程来执行需求的操作,在你的线程中使用Synchronize方法来调用这个分离的过程。如:

procedureTMyThread.PushTheButton;

begin

Button1.Click;

end;

procedure TMyThread.Execute;

begin

....

Synchronize(PushTheButton);

....

end;

Synchronize等待主VCL线程进入消息循环,然后执行相应的方法数据访问组件和图形组件都是线程安全的,不需要使用主VCL线程。

4.2 Thread-local变量

Thread-local变量是一种线程内的全局的变量,但是并不与其他的线程实例共享。声明thread-local变量是在threadvar区中声明,如:

threadvar

x : integer;

threadvar区只适用于全局变量。

5. 编写清除代码(Clean-up Code)

线程结束时执行的清除代码可以集中起来。当线程关闭前,一个OnTerminate事件发生。将清除代码都放在OnTerminate事件的处理代码中,这样,这些代码就总会被执行。

OnTerminate事件处理并不是作为线程的一部分运行,它是在主VCL线程环境(Context)下运行。有两个含义:在OnTerminate事件处理中不能使用任何线程局部变量可以安全的访问任何组件和VCL对象,而不必担心会与其它的线程冲突

6.避免同时访问

为了避免与其他线程在访问一个全局对象货变量时发生冲突,需要在执行线程代码时锁定其他线程的执行,直至完成操作。VCL支持三种技术来达到这个目的:

(1) 锁定对象:有些对象自己有锁定的功能,如canvas

(2) 使用critical区

如果对象没有提高内置的锁定功能,需要使用critical区,Critical区在同一个时间只也许一个线程进入。为了使用Critical区,产生一个TCriticalSection全局的实例。TcriticalSection有两个方法,Acquire(阻止其他线程执行该区域)和Release(取消阻止)

每个Critical区是与你想要保护的全局内存相关联。每个访问全局内存的线程必须首先使用Acquire来保证没有其他线程使用它。完成以后,线程调用Release方法,让其他线程也可以通过调用Acquire来使用这块全局内存。

警告:Critical区只有在所有的线程都使用它来访问全局内存,如果有线程直接调用内存,而不通过Acquire,会造成同时访问的问题。例如:LockXY是一个全局的Critical区变量。任何一个访问全局X

Y的变量的线程,在访问前,都必须使用Acquire

LockXY.Acquire; { lock out other threads }

try

Y := sin(X);

finally

LockXY.Release;

end;

(3) 使用multi-read exclusive-write synchronizer

当你使用critical区保护全局内存时,同一个时间内只允许一个线程使用这块内存。这也许会超过你的要求,特别是对于那些经常读而很少写的对象或变量。在多线程内,当没有线程对同样的内存进行写操作时,同时读它是没有任何问题。当你有一些全局变量需要经常读而很少写时,可以使用TmultiReadExclusiveWriteSynchronizer保护它们。这个对象象Critical section

但是当内存没有线程在写它时,允许多个线程读取一个内存。

为了使用multi-read exclusive-write synchronizer,产生一个全局的 TmultiReadExclusiveWriteSynchronizer实例,与你想要保护的内存相关联。每个线程如果项读取该内存,必须先调用BeginRead方法。它确信没有其他的线程在写内存。读完后,调用EndRead。写内存时,调用BeginWrite,写完后,调用 EndWrite。

警告:同Critical section一样,multi-read exclusive-write synchronizer也只有在所有的线程都使用它访问同一块全局内存时才有效。直接访问该内存将会导致同时访问问题。

7.线程对象的执行

使用线程时,首先产生一个线程的实例,可以立刻开始运行线程,也可以开始把它置于挂起(Suspended)状态,以后使用Resume方法运行它。将构造函数中的CreateSuspended参数置为false,线程将创建后立刻运行,如:SecondProcess := TMyThread.Create(false); {create and run the thread }一般在单处理器的机器上,一个进程适合产生16个线程,如果线程都在运行,那么线程的数目要更少一些。

暂停线程:调用suspend

恢复线程:调用resume

终止线程:调用Terminate,它将线程的Terminated特性置为true。如果Execute编写合理,它将周期性检查Terminated,当Terminated为True时,将终止线程的执行。如:

procedure TMyThread.Execute;

begin

while not Terminated do

PerformSomeTask;

end;

缓存线程

当应用需要同一个线程的多个实例(多次运行一个线程),可以缓存线程,以后重用,以提高性能,而不是每次创建一个新的线程。为了缓存线程,使用一个线程列表来维护线程。

VB如何用VB在桌面建立快捷方式 VB如何在 VB 中控制 Modem 行为? VB如何在VB中判断Windows9x的运行模式 VB如何在Visual Basic中实现异步执行程序 VB如何在开机时自动更换墙纸? 使回车具有 Tab 的功能-VB资料 输入时,自动转换成小写? -VB资料 显示多媒体信息 -VB资料 也谈Windows 下的自动存盘 -VB资料 一个小巧精致的CPU监视器 -VB资料 应用VB4.0实现工业控制的实时曲线和历史曲线 应用程序中实现关机功能-VB资料 萤幕抓取与萤幕保护程式 -VB资料 用VB5.0创建Windows快捷方式 用VB5.0收集键盘和鼠标信息 用VBA限制非注册软件使用时间 用VB编程检测当前电池使用情况 用VB编写定时关闭计算机的程序 用VB编写键盘拦截程序 用VB函数轻松访问系统注册表 用VB设计一个定时闹钟程序 用VB实现拖放功能 在VB中启动控制面板 在VB中异步执行程序 在Visual Basic中终止Windows 95 在关机或Logff前信息的拦截-VB资料 VB怎样捕捉窗体的鼠标? VB怎样存取注册表信息 VB怎样改变双击鼠标的时间间隔? VB怎样关闭一个正在运行的程序 VB怎样限制鼠标移动 如何实现Windows 2000 Server 远程拨号登录?请奉上你的经验和智慧!!! 莱鸟级的问题,你敢来挑战吗? TADODataSet 读磁盘文件是怎么用的? 我的毕业设计,一百分的送分题啊!!!!!!!!!!!!!!!!!1 请教这个函数的作用 //创建列的问题,谁帮我看一看缺什么,谢了 如何在本地访问远程数据库,用什么样的方法在速度、安全上都好一些 请大家指点下在深圳哪里可以办个边防证?谢谢 各位大侠,谁能介绍一下utf8,还有怎么把它转到gb2132编码呢? 我的毕业设计,一百分的送分题啊!!!!!!!!!!!!!!!!!1 窗体问题。。。 现有一个小项目: 怎样动态增加表格? 有人解决了jive的中文问题吗?? 报表就是查询结果吗?用VB很难做吗?为什么这么多人讨论,请问设计报表难点是什么? 请问我的VC地ClassView无法打开,有什么快速的方法可以打开 一个关于tomcat中servlet的棘手问题..... 谁可以帮我提供一个PHP的站内目录管理程序! 请问c++中,函数重载和虚函数有什么区别,在实现多态性方面有差别吗? 现有一个小项目: 如何对多个按钮的BN_ClICK进行映射 SQLserver备份与恢复 Delphi中怎样声明一个类?怎样实现多态?如果要在类库的一个类中添加一个方法又怎么做? 然后怎样封装它?是不是封装以后维护就非常简单? 可 计算机网络--〉清华大学出版社,作者:Andrew S Tanenbaum哪里有电子版下载 把播放F4的时间上《我们程序员都是活雷锋》 随便问问:VC能不能调用Access中的Form,Report 用ADO在线程中打不开数据库,请帮忙 如何在VB中动态的加载Dll,并使用其加载的函数??? 高手们看过来 Oracle初学,兄弟们多帮忙了! 怎么打开一个.txt文件,然后一行一行读取? 请问大家知道一个局域网里的IP在因特网上如何表示的呢。 请问各位,如何在我的程序中用代码生成Access数据库? 神啊,救救我吧,我想要含笑半步喋=== 请教NT4。0下的IE2。0怎样升级到IE6。0或IE5。0? 我要在程序中重载CBitmap类的一个函数,请问如何做 为什么我在bcb的new中找不到multitier(就是多层)选项页 请问如何知道数据库中有哪些表存在?在线等待 向各位大侠求救中 这是数据库的缺点吗? Choice.asp?VehicleType=a+&VehicleColor=Red + 传不到Choice.asp 如何获取文件扩展名关联信息 急!应选择什么样的服务器? 请问哪里有关于DOS和BIOS的系统功能调用的e书籍下载?谢谢指点 想用bcb的DirectX编一个显示器(第二个)的独占程序!希望专家指点!也欢迎大家来交流! 你碰到过这样的问题吗? What is meaning "$1 $2 " in perl? 配置支持ISAPI调用的 apache 服务器 怎样判断内存有没有被释放? window2000的安装和IE的问题 像我這樣的Boy,是否可以找到GF??? 欧洲中世纪统治欧洲的是什么教 硬脂酸级别中有分橡胶级、食品级等等级别,那硬脂酸的各种型号,各对应什么级别啊?比如说1801硬脂酸级别中有分橡胶级、食品级还有什么级别的区分?硬脂酸1801、1840等等这些型号对应的又是 液汞是什么东西?是纯净物吗? 什么叫PEG? 橡胶级硬脂酸是个什么概念?什么是橡胶级硬脂酸?有什么相应的标准?是不是就是作为橡胶添加剂的硬脂酸? 学校有哪些安全隐患 生物学中缩写HLA 和 硬脂酸铈在橡胶中用作什么助剂? 有哪些安全隐患? 高中生物的PEP和PEG都具体指什么,有什么不同? 那位师傅知道硬脂酸在再生橡胶中起什么作用啊? GB2893-2008安全色的红色、黄色、蓝色、绿色色标值是多少? PEG是什么意思 水银是什么?吃了会怎么样呢? 怎样确定一氯代物的种类2,2-二甲基戊烷,3-乙基戊烷,怎样数它们的一氯代物种类呢?重复的应该怎么办?可是你的答案好象不对啊,和老师批改的不一致,你把3-乙基戊烷再解释下,重复的只算一个, PEG是什么? 吃了一点水银会死吗 一氯代物和两氯代物的种类怎么求? 酱油,糖水是导体还是绝缘体 股票的PEG是什么意思 关于烷烃一氯代物种类的问题比如说这个:CH3-CH-CH2-CH2-CH3| CH3 怎么判断他有几个等效氢,并且关于哪个对称!应该是这样写的:下面那个 | 对着第2个CH 欧洲中世纪城市特点欧洲中世纪城市的特点是什么?具体有哪几个方面?我说在城市建设方面的 从政治经济等不同角度的 不小心碰到水银怎么办今天我后桌的同学把温度计弄破了,里面有个小小的银色水银珠,几个男生用橡皮按破了,变成了很小很小的珠子,散在桌子上到处都是,然后他们就用书把水银往我这推,掉 丙烷的氯代物的种类 欧洲中世纪城市的特征、简况有哪些? 温度计的水银漏了怎么办?我弟不小心摸到了怎么办?该怎么收拾水银啊? 有机物氯代物的种类如何数?请举例说明!越清楚越好! 欧洲中世纪某城市发展简介简单点 用聚乙二醇融合原生质体的依据是 谁有瓦斯隐患定期排查治理工作制度?帮帮 高分子合金的相容性是指什么啊 请问,聚乙二醇(PEG)是一种无电荷的直链大分子多糖吗? 安全色中的蓝色表示什么 安全色有哪几种 如果不小心吃了一点水银会怎么样 向蒸馏水中加几滴硝酸银溶液的现象是什么如题,还有其目的是什么?它的目的可不可以说是检验其中是否还有杂志呢? 安全色是? 不小心吃了水银,真苦! 国家《安全色》的蓝色是表示什么?国家颁布的《安全色》标准中,红色表示危险,黄色表示警戒,蓝色表示(?绿色表示安全。 关于欧洲中世纪封建制度的一些问题呃,这些问题都是关于欧洲中世纪那时候的,说清楚点就OK,不用长篇大论撒.鞠躬.^_^(本人看到Social Study就头痛,) 1.城堡在中世纪(欧洲那边)扮演了什么 不小心误吞水银如何处理? 硝酸银溶解于蒸馏水可以成为硝酸银水溶液吗? 国家标准(GB2893--82)中规定的四种安全色是( ) 不小心吞了水银, 中世纪西欧的政治制度和古代日本有什么相同和差异 欧洲中世纪有哪些特点 金刚石和石墨是单质还是混合物 安全隐患有什么 关于欧洲中世纪服装有谁知道有什么书介绍欧洲中世纪服饰的书么,类似于乱世佳人里面的那种衣服~ 氯化钠和纯碱反应吗?为什么? 黄色象征的意义 欧洲中世纪指的是哪段时间? 家庭存在的安全隐患交通安全方面的,两到三句话 黄色代表什么意思? 求几部欧洲中世纪电影求几部欧洲中世纪的电影,最好能是欧洲黑暗时代的,或者时间段是在公元500年至公元1000年间得到电影,什么题材的都可以,满足这两个时间段之一的给分,最好能给出影片 氯化钠如何一步反应为碳酸钠 黄色表示什么意思 欧洲中世纪指哪段历史? 安全隐患有哪些 黄代表什么意思
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘