发信人: lofe ()感激生活(), 信区: BorlandDev
标  题: DELPHI32下的多线程程序设计 
发信站: 哈工大紫丁香 (Mon Sep  4 16:06:35 2000), 转信

DELPHI32下的多线程程序设计 

梁毅 李韬 
  我们知道,win95或winNT都是“多线程”的操作系统
,在DELPHI2.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Κclass(TThread)

  private

  fQuery:tQuery;

  protected

  procedureExecute;override;

  public

  constructorCreate(Suspended:Boolean;Query:
TQuery);

  end;

  implementation

  constructor

  TQueryThread.Create(Suspended:Boolean;Quer
y:TQuery);

  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选项,再选“T
ThreadObject”项目,DELPHI就会为你构造基本的程序模
块。然后我们可以根据需要再做相应的修改。

  进程的执行:

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

  procedureTForm1.Button1Click(Sender:TObject
);

  begin

  {建立一个运行的进程}

  TQueryThread.Create(False,Query1);

  end;

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

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

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

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

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

  unitBncThrd;

  interface

  uses

  WinProcs,Classes,Graphics,ExtCtrls;

  type

  TBounceThreadΚclass(TThread)

  private

  FShape:TShape;

  FXSpeed:Integer;

  FYSpeed:Integer;

  procedureMoveShape;

  protected

  procedureExecute;override;

  public

  constructorCreate(

  Suspended:Boolean;

  Shape:TShape;

  XSpeed,YSpeed:Integer);

  propertyShape:TShapereadFShape;

  end;

  implementation

  procedureTBouad.MoveShape;

  var

  MaxHeight,MaxWidth:Integer;

  begin

  withFShapedo

  begin

  Left:ΚLeft+FXSpeed;

  Top:ΚTop+FYSpeed;

  if(LeftΙ0)or

  (Left+WidthΛParent.Width)then

  FXSpeed:ΚFXSpeed*-1;

  if(TopΙ0)or

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

  FYSpeed:ΚFYSpeed*-1;

  end;

  end;

  procedureTBounceThread.Execute;

  begin

  WhilenotTerminateddo

  begin

  Synchronize(MoveShape);

  end;

  end;

  constructorTBounceThread.Create(

  Suspended:Boolean;

  Shape:TShape;

  XSpeed,YSpeed:Integer);

  begin

  inheritedCreate(Suspended);

  FShape:ΚShape;

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

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

  FreeOnTerminate:ΚTrue;

  end;

  end.

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

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

  procedureTForm1.Button1Click(Sender:TObject
);

  begin

  TBounceThread.Create(False,Shape1,1,2);


  TBounceThread.Create(False,Shape2,2,3);


  end;

  

   

返回主页 

--
      -------丈夫处世兮立功名;立功名兮慰平生。
                  慰平生兮吾将醉;吾将醉兮发狂吟!--------
                                                      
※ 修改:.haojs 于 Sep  4 16:04:02 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.579毫秒