其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

DELPHI下的多线程程序设计


发布日期:2019年09月29日
 
DELPHI下的多线程程序设计
我们知道win或winNT都是多线程的操作系统在DELPHI 我们可以充分利用这一特性编写出多线程的应用程序

对以往在DOS或位windows下写程序的人来说多线程仍然是陌生的但如同以前我们从DOS下的单任务过渡到windows下的多任务如今我们又必须过渡到多线程领域毕竟计算机时代是在不断发展的不过幸运的是在DELPHI下进行多线程程序设计并不需要我们去学习庞大的WINAPI函数我们可以利用DELPHI下标准的多线程类TThread来完成我们的工作

TThread是一个abstract(抽象)类也就是说并不需要根据TThread来声明变量(而且根据TThread声明的变量也是完全无用)我们要做的是把TThread作为基类用继承的形式来生成子类实际上根据TThread来写多线程应用程序是非常容易的

下面就是一个基本的继承TThread生成的多线程类

QuerThrd.Pas

unitQuerThrd

interface

uses

ClassesDBTables

type

TQueryThreadΚclass(TThread)

private

fQuerytQuery

protected

procedureExecuteoverride

public

constructorCreate(SuspendedBooleanQueryTQuery)

end

implementation

constructor

TQueryThread.Create(SuspendedBooleanQueryTQuery)

begin

inheritedCreate(Suspended)

fQueryΚQuery

FreeOnTerminateΚTrue

end

procedureTQueryThread.Execute

begin

fQuery.Open

end

end.

在上面这个简单的例子中我们构造了一个TThread的子类TQueryThread用于在后台执行数据库查询在该类的Create函数中传递了两个参数Suspended和Query其中Suspended用于控制线程的运行如果Suspend为真TQueryThread类的线程在建立后将立即被悬挂一直到运行了Resume方法该线程才会继续执行Query参数用于接受一个已经存在的Query控件(在窗体中真正的Query控件)而使它在多线程的情况下运行Execute是最重要的过程它是类TQueryThread的执行部分所有需要在这个多线程类中运行的语句都必须写在这个过程里

实际上构造自己的多线程类时并不需要输入所有的这些代码选择DELPHI的File菜单下的new选项再选TThreadObject项目DELPHI就会为你构造基本的程序模块然后我们可以根据需要再做相应的修改

进程的执行

假设我们已经建立了一个窗体FORM窗体中有我们将要使用的查询控件Query那么我们在该单元的USES部分加入上面写的QuerThrd单元

procedureTForm.ButtonClick(SenderTObject)

begin

{建立一个运行的进程}

TQueryThread.Create(FalseQuery

end

如果这个过程被执行那么窗体中的查询控件Query就会自动在多线程的环境下运行查询注意TQueryThread类中只有Create而没有Free动态建立类以后又忘记删除是我们常犯的错误之一不过在这里由于我们指定了FreeOnTerminate(运行完即删除)为真所以当Execute里的语句执行完后TQueryThread类占据的内存控件将被自动释放

然而还有一个问题值得我们注意由于同一时刻可以有多个线程同时运行那么我们还必须解决好同步的问题如果几个多线程程序之间没有任何关联那么它们之间也不会有任何沖突但实际上可能同时运行几个多线程的数据库应用程序由于需要共享相同的数据库资源我们还需要为Query增加一个Tsession控件

其实虽然我们也许没有亲自使用过Session控件但实际上在所有的数据库访问时DELPHI都会自动建立一个临时的Session控件使用完后又动态地删除掉它在平常的数据库编程时用不着我们亲自来操作但在数据库多线程执行的情况下为了不相互沖突我们必须为每个数据库访问都定制自己的Session控件这个步骤非常简单我们只需要在窗体中增加一个Session控件然后给它的属性Sessionname写一个任意的名字并再在QuerySessionname中写一个相同的名字这样我们的数据库程序就安全了

另一类需要解决同步问题的是那些对VCL资源进行操作的程序这类的程序非常多好在解决的方法也非常简单

我们可以看下面这样一个程序

unitBncThrd

interface

uses

WinProcsClassesGraphicsExtCtrls

type

TBounceThreadΚclass(TThread)

private

FShapeTShape

FXSpeedInteger

FYSpeedInteger

procedureMoveShape

protected

procedureExecuteoverride

public

constructorCreate(SuspendedBooleanShapeTShapeXSpeedYSpeedInteger)

propertyShapeTShapereadFShape

end

implementation

procedureTBouad.MoveShape

var

MaxHeightMaxWidthInteger

begin

withFShapedo

begin

LeftΚLeft+FXSpeed

TopΚTop+FYSpeed

if(LeftΙ)or

(Left+WidthΛParent.Width)then

FXSpeedΚFXSpeed*-

if(TopΙ)or

(Top+HeightΛParent.Height)then

FYSpeedΚFYSpeed*-

end

end

procedureTBounceThread.Execute

begin

WhilenotTerminateddo

begin

Synchronize(MoveShape)

end

end

constructorTBounceThread.Create(SuspendedBooleanShapeTShapeXSpeedYSpeedInteger)

begin

inheritedCreate(Suspended)

FShapeΚShape

FXSpeedΚXSpeed{X轴走向的速度}

FYSpeedΚYSpeed{Y轴走向的速度}

FreeOnTerminateΚTrue

end

end.

这是一个多线程的碰碰球游戏你可以有多个不同的球它们分属不同的线程各自独立的在屏幕上碰撞显然由于多个球运行的显示会同时操作VCL资源为了安全我们在Execute过程中的执行部分加入了Synchronize(MoveShape)来调用MoveShape过程实际上在任何需要操作VCL资源的地方例如窗体位图都应加入Synchronize调用

执行时我们可以新建一个程序然后在USES部分加入以上的BncThrd单元再在它的窗体FORM上加入两个Shape控件Shape和ShapeShape可以是一个矩形而Shape是一个圆加入以下的代码就可以让矩形和圆动起来

procedureTForm.ButtonClick(SenderTObject)

begin

TBounceThread.Create(FalseShape

TBounceThread.Create(FalseShape

end

上一篇:Delphi中票据凭证的精确打印

下一篇:利用Delphi的TJPEGImage控件把BMP转化成JPEG