搜档网
当前位置:搜档网 › DELPHI下的多线程程序设计

DELPHI下的多线程程序设计

DELPHI下的多线程程序设计
DELPHI下的多线程程序设计

DELPHI下的多线程程序设计

我们知道, win95 或 winNT 都是“多线程”的操作系统,在 DELPHI 2.0 中,我们可以充分利用这一特性,编写出“多线程”的应用程序。

对以往在DOS或16位windows下写程序的人来说,多线程”仍然是陌生的,但如

同以前我们从DOS下的单任务过渡到 windows3 . 1下的多任务,如今我们又必须过渡到“多线程”领域,毕竟计算机时代是在不断发展的。不过,幸运的是,在 DELPHI2 .0 下进行多线程程序设计并不需要我们去学习庞大的 WIN32API 函数,我们可以利用 DELPHI 下标准的多线程类TThread 来完成我们的工作。

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

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

QuerThrd.Pas

unitQuerThrd ;

interface

uses

Classes, DBTables;

type

TQueryThread K class (TThread)

private

fQuery:tQuery;

protected

proced u reExecute; override;

public

constructorCreate( Suspended: Boolean;Query:TQuery);

end;

implementation

constructor

TQueryThread.Create(Suspended:Boolean;Query:TQuery);

begin

inheritedCreate ( Suspended);

fQuery : K Query;

Free On Term in ate: K True

end;

procedureTQueryThread. Execute;

begin

fQuery.Open;

en d;

en d.

在上面这个简单的例子中,我们构造了一个TThread的子类TQuery Thread,用于

在后台执行数据库查询。在该类的Create函数中,传递了两个参数Suspended和Query,其中Suspended用于控制线程的运行,如果 Suspend为真,TQueryThread类的线程在建立后将立即被悬挂,一直到运行了Resume方法,该线程才会继续执行,Query参数用于

接受一个已经存在的 Query控件(在窗体中真正的Query控件)而使它在多线程的情况

下运行。Execute是最重要的过程,它是类 TQueryThread的执行部分,所有需要在这个多线程类中运行的语句都必须写在这个过程里。

实际上构造自己的多线程类时,并不需要输入所有的这些代码,选择DELPHI的File

菜单下的new选项,再选“TThreadObject项目,DELPHI就会为你构造基本的程序模块。然后我们可以根据需要再做相应的修改。

进程的执行:

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

procedureTForm1 . Button1Click ( Sender: TObject);

begi n

{建立一个运行的进程}

TQueryThread . Create (False, Query1);

en d;

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

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

其实,虽然我们也许没有亲自使用过Session控件,但实际上,在所有的数据库访问

时DELPHI都会自动建立一个临时的 Session控件,使用完后又动态地删除掉它。在平常

的数据库编程时,用不着我们亲自来操作,但在数据库多线程执行的情况下,为了不相互冲突,我们必须为每个数据库访问都定制自己的Session控件。这个步骤非常简单,我们只需要在窗体中增加一个 Session控件,然后给它的属性“ Sessio nn ame”一个任意的名字,并再在Query1的“Sessionname”写一个相同的名字。这样我们的数据库程序就安全了。

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

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

unitBncThrd ;

in terface

uses

Win Procs, Classes, Graphics, ExtCtrls ;

type

TBounceThread K class (TThread)

private

FShape: TShape;

FXSpeed: Integer;

FYSpeed: Integer ;

procedureMoveShape;

protected

procedureExecute;override;

public

constructorCreate (Suspended Boolean;Shape: TShape;XSpeed, YSpeed: Integer);propertyShape: TShapereadFShape

en d;

impleme ntati on

procedureTBouad. MoveShape;

var

MaxHeight , MaxWidth : Integer;

begi n

withFShapedo

begi n

Left: K Left+ FXSpeed;

Top: KT op+ FYSpeed;

if ( Left 1)0 or

(Left + Width A Pare nt Width) the n

FXSpeed: K FXSpeec F— 1 ;

if (Top I0 or

(Top+ Height A Par ent. Height) then

FYSpeed: K FYSpeec F— 1 ;

en d;

en d;

procedureTBounceThread. Execute;

begi n

While no tTerm in ateddo

begi n

Synchronize ( MoveShape);

en d;

en d;

constructorTBounceThread . Create (Suspended: Boolean; Shape: TShape; XSpeed, YSpeed: Integer);

begi n

inheritedCreate (Suspendec);

FShape: K Shape

FXSpeed: K XSpeed {X轴走向的速度}

FYSpeed: K YSpeed; { Y 轴走向的速度}

Free On Term in ate: K True

en d;

en d.

这是一个多线程的碰碰球游戏,你可以有多个不同的球,它们分属不同的线程,各

自独立的在屏幕上碰撞。显然,由于多个球运行的显示会同时操作VCL资源,为了安全,

我们在Execute过程中的执行部分加入了Synchronize( MoveShape)来调用 Move Shape

过程,实际上,在任何需要操作 VCL资源的地方,例如窗体、位图,都应加入Synchronize 调用。

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

procedureTForm1 . Button1Click ( Sender: TObject); begi n

TBounceThread. Create (False, Shape! 1, 2);

TBounceThread. Create (False, Shape? 2, 3); en d;

相关主题