delphi多线程(2)

****************************************************************

****************************************************************
TThread在Classes单元中声明,直接从TObject继承下来的,因为,它不是组件.TThread是个抽象类,所以不能创建TThread的实例,而只能创建其派生类的实例.

利用TThread类来编写多线程应用程序的一般步骤如下:

[步骤一] 从TThread类派生出一个新的线程类.
[步骤二] 创建线程对象
[步骤三] 设置线程对象的属性,比如优先级等.
[步骤四] 根据具体情况挂起或唤醒线程.
[步骤五] 结束线程.

从TThread类派生出一个新的线程类的过程非常简单:通常菜单"File|New|Other..."打开"New Items"对话框,选中"New"页的"Thread Object"项,单击"OK"按钮,接着在弹出的"New Thread Object"对话框中输入新的线程类的名称.通常线程类的名称以T开头,以Thread结束,例如"TTestThread".

TThread类还有以下的一些属性、方法和事件:

Priority属性:整型,设置线程的优先级.
Return Value属性:返回值,即当线程结束时返回给其他线程的一个数值.
Suspended属性:判断线程是否被挂起.
ThreadID属性:线程标识号,是整个系统中线程的标识号.
DoTerminate过程:产生一个OnTerminate事件,但是不结束线程的执行.
Resume过程:唤醒一个线程继续执行.
Suspend过程:挂起一个线程.
Synchronize过程:由主VCL线程调用的一个同步过程.
Terminate过程:将Terminated属性设置为True,终止线程的执行.
WairFor方法:等待线程的终止并返回Return Value属性的数值.
线程优先级的设定:
TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical);
下面进行一个简单的示例:
线程单元:
unit untPaintThread;
interface
uses
  Classes;
type
  PaintThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;
implementation
uses untMain,Graphics;
procedure PaintThread.Execute;
var
  x,y: Integer;
begin
  { Place thread code here }
  Randomize;
  repeat
    x := Random(Form1.ClientWidth);
    y := Random(Form1.ClientHeight);
    with  Form1.Canvas do
    begin
      Lock;   //使用vcl中的资源的时候进行相应的加锁
      try
        Pixels[x,y] := clBlue;
      finally
      Unlock; // 使用完后进行相应的释放
      end;  
    end;
  until Terminated;
end;
end.
主线程单元:
unit untMain;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,untPaintThread, StdCtrls;
type
  TForm1 = class(TForm)
    btn1: TButton;
    btn2: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    pthread: PaintThread;
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
begin
    pthread.Resume;
end;
procedure TForm1.btn2Click(Sender: TObject);
begin
   pthread.Suspend;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  pthread := PaintThread.Create(true);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
    pthread.Free;
end;
end.
多线程程序访问VCL的时候要特别注意,只能逐个地实现对VCL的访问.具体可以采用下面的两个方法:
(1) 锁定VCL对象
对于一些具有锁定功能的对象,可以在锁定之后再进去具体操作,比如上面的方法!!!.
(2) 使用Synchronize函数
TThread类的Synchronize过程声明如下:

type TThreadMethod=procedure of object;
procedure Synchronize(Method:TThreadMethod);

其他参数Method为一个不带参数的过程名.在这个不带参数的过程中是一些访问VCL的代码.
对Synchronize的调用是在Execute过程中,用来避免对VCL的并发访问.程序运行期间的具体过程实际上是由Synchronize过程来通知主线程,然后主线程在适当的时机执行Synchronize过程的参数列表中不带参数的过程.在多个线程的情况下,主线程将Synchronize过程所发的通知放到消息队列中,然后逐个地响应这些消息.通过这种机制Synchronize实现了线程之间的同步.
unit untmain;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin, ImgList;
type
  TAnimThread = class(TThread)
  private
    bt: TBitmap;
    procedure DrawGraphics;
  protected
    procedure execute; override;
  end;
type
  TForm1 = class(TForm)
    il1: TImageList;
    SpinEdit1: TSpinEdit;
    lbl1: TLabel;
    lbl2: TLabel;
    btn1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    anmthread: TAnimThread;
  end;
var
  Form1: TForm1;
  run:   Boolean;
implementation
{$R *.dfm}
{ TAnimThread }
procedure TAnimThread.DrawGraphics;
begin
   //这个地方使用了双缓冲技术
   Form1.Canvas.CopyRect(Bounds(0,0,Form1.Width,32),bt.Canvas,Bounds(0,0,Form1.Width,32));
   BitBlt(Form1.Canvas.Handle,0,0,Form1.Width,32,bt.Canvas.Handle,0,0,SRCCOPY);
end;
procedure TAnimThread.execute;
var
  x,i: Integer;
  dir: Boolean;
begin
  bt := TBitmap.Create;
  try
  bt.Width := Form1.ClientWidth;
  bt.Height := 32;
  bt.Canvas.Pen.Color := clPurple;
  bt.Canvas.Brush.Color := clSkyBlue;
  bt.Canvas.Rectangle(0,0,Form1.Width,32);
  dir := false;
  x := 0;
  i := 0;
  repeat
  begin
     Inc(i);
     bt.Canvas.Rectangle(0,0,Form1.Width,32);
     Form1.il1.Draw(bt.Canvas,x,0,i);
     Synchronize(DrawGraphics);
     Sleep(1* 100);
     if (i < 0) or(i>300) then
     dir := not dir;
     if dir then Inc(x) else Dec(x);
     if i > Form1.il1.Count - 1 then
        i := 0;
  end;
  until terminated;
  finally
    bt.Free;
  end;  
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  run := false;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
    if not anmthread.Terminated then
    anmthread.Free;
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
    run := not run;
    if run then begin
       anmthread := TAnimThread.Create(false);
    end  else
        anmthread.Free;
    if btn1.Caption = '开始' then
        btn1.Caption := '结束'
    else btn1.Caption := '开始';
end;
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi是一门古老而优秀的编程语言,在多线程编程方面也有一些特殊的处理方式。多线程在开发中是必备的知识,但相对来说也是比较难的知识点。 多线程可以将一个进程划分为多个线程,每个线程轮流占用CPU运行时间和资源。在多线程中,可以通过优先级管理来使重要的程序优先操作,同时也提高了任务管理的灵活性。另外,在多CPU系统中,不同的线程可以在不同的CPU中执行,从而实现真正的多任务处理。 在Delphi中,使用TThread类来实现多线程编程。TThread类是Delphi中用于创建和管理线程的基本类,它提供了一些方法和属性来控制线程的执行流程。我们可以继承TThread类,重写Execute方法来编写自己的多线程任务逻辑。 下面是一个简单的例子来说明如何在Delphi中使用多线程: ```delphi unit MainForm; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TMyThread = class(TThread) protected procedure Execute; override; end; TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TMyThread.Execute; begin // 在这里编写你的多线程任务逻辑 Sleep(500); Synchronize(procedure begin Form1.Memo1.Lines.Add('Hello from thread!'); end); end; procedure TForm1.Button1Click(Sender: TObject); var MyThread: TMyThread; begin MyThread := TMyThread.Create(True); // 创建一个线程对象 MyThread.FreeOnTerminate := True; // 设置线程结束后自动释放 MyThread.Start; // 启动线程 end; end. ``` 在上面的示例中,我们创建了一个TMyThread类,继承自TThread类,并重写了Execute方法。在Execute方法中,我们可以编写我们自己的多线程任务逻辑。在Button1Click事件中,我们创建了一个TMyThread对象,并调用其Start方法来启动线程。 以上是Delphi中多线程编程的简单介绍,希望对你有帮助。如果你需要更详细的信息,请参考引用和引用中提到的书籍和文章。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值