新手可以借鉴    《〈在Delphi 中利用线程》的文章中, 其基本思想就是直接调用Windows API 的CreateThread 函数来创建一个线程。那么, 利用Delphi 自身所定义的丰富的标准例程库和数量更多、内容更广泛的( 非) 可视类库进行处理, 以取代直接调用Windows API 函数可否实现呢?回答是肯定的, 而且更有效、更保险:
---- 方法一: 利用RTL 库的System 单元中定义的一个标准例程BeginThread。此例程完整封装了Win32 的CreateThread 函数, 是一个带有异常处理的标准Pascal 函数, 几乎可以处理所有自身的异常, 相对于使用Win32 的CreateThread 函数, 其安全系数大大增强。
---- BeginThread 函数在创建时, 不是如CreateThread 函数仅仅完成两项任务: 创建一个线程; 创建一个能作为线程入口的函数。还增加了几项保护措施:
---- 把System 单元中声明的全局变量IsMultiThread 设为TRUE, 这样Delphi 的堆栈管理器就知道当前有多个线程在运行, 从而防止多个线程同时修改它的内部结构;
---- 另外, 在调用BeginThread 函数时, 可创建一个异常框架, 允许系统缺省的异常处理句柄捕获任何未有被处理的异常线程。如果在线程函数中有任何未被处理的异常, 会自动产生一个退出代码, 或者线程返回的句柄为0, 表示线程没有创建成功, 则应用程序将会调用EndThread 过程(Procedure EndThread(ExitCiode:Integer)), 自动终止线程的运行。
---- 其完整声明如下:
 function BeginThread( SecurityAttributes: Pointer;
 StackSize: Integer;
 ThreadFunc: TThreadFunc;
 Parameter: Pointer;
 CreationFlags: Integer;
 var ThreadId: Integer): Integer;
---- 各参数的使用特点类似CreateThread 函数:
---- SecurityAttributes 参数是一个指向SECURITY_ATTRIBUTES 结构的指针, 其目的用于设置线程的访问权限,nil 表示为默认的安全属性。
---- StackSize 参数用于设置分配给线程的栈空间大小,0 表示用默认值。
---- ThreadFunc 用于指定一个函数, 该函数在线程创建后开始执行代码时调用。
---- Parameter 参数传递给ThreadFunc 参数所指定的函数, 常为nil, 或者设为一个32 位的指针, 指向一个数据结构。
---- CreationFlags 参数用于指定线程创建后是不是立即执行,0 表示立即执行,CREATE_SUSPENDED 表示处于挂起状态。
---- ThreadId 参数表示为每个线程唯一的识别号, 当BeginThread 函数返回后, 此参数就是线程的识别号。
---- 返回值为该线程的句柄, 如果为0, 表示表示线程没有创建成功, 可以调用Windows 的GetLastError 函数分析错误的原因。
---- 方法二: 利用Delphi 的VCL 库中TThread 对象。Delphi 的一个缺陷是不支持多个线程同时访问它的VCL 库, 但Delphi 的设计者们并没有刻意掩饰这个缺陷, 而是专门创建了一个TThread 对象以解决这个问题。这个TThread 对象封装了Windows API 和System 单元中有关线程运用的多个函数和例程, 利用操作系统分时段给各线程方式控制各个线程的“休眠”与“唤醒”以达到线程工作的同步, 当被“唤醒”后就调用TThread 对象的Synchronize 过程通知主线程, 让主线程去真正地访问VCL, 使得在一个应用程序中同时访问多个VCL 库成为了可能, 当然, 对于进行一般的多线程编程, 就更加简单了。
---- 在使用上它与Delphi 中大多数对象不同的是TThread 类是一个带有虚拟抽象对象方法的类, 我们不能直接创建TThread 对象的实例, 而必须先声明一个以TThread 对象为基类的类, 再用这个派生类创建实例和操纵线程具体的类属性和方法。具体声明可参看其源代码(c:\program files\borland\delphi 3\source\vcl\classes.pas) 或其它参考书。
---- 结合上述两种方法给出一例子程序, 以显示利用Delphi 自身强大的处理功能如何建立及使用线程, 创建一个Form 窗体,Caption 设为“线程创建例子程序”, 在窗体中放入四个TButton 控件, 分别设置Caption“例程创建成功”、“例程创建失败”和“类创建成功”、“类创建失败”。Name 分别为“routines1Button”、“routines2Button”和“class1button”、“class2button”, 一个TEedit 控件,text 设置为“”:
unit threadsimple;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
 StdCtrls;
type
 TForm1 = class(TForm)
 Edit1: TEdit;
 class1button: TButton;
 class2button: TButton;
 routines1Button: TButton;
 routines2Button: TButton;
 procedure class1buttonClick(Sender: TObject);
 procedure routines1ButtonClick(Sender: TObject);
 procedure routines2ButtonClick(Sender: TObject);
 procedure class2buttonClick(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
 tmythread=class(tthread)
 count:integer;
 myedit:tedit;
 procedure show;virtual;abstract;
 constructor create(myedit1:tedit);
 end;
 thread1=class(tmythread)
 procedure show; override;
 procedure execute;override;
 end;
 thread2=class(tmythread)
 procedure show; override;
 procedure execute;override;
 end;
var
 Form1: TForm1;
implementation
{$R *.DFM}
procedure mythreadfunc;// 创建的线程函数
var
 i:integer;
 dc:hdc;
 s:string;
begin
 for i:=0 to 100000 do
 begin
 s:=inttostr(i);
 dc:=getdc(form1.edit1.handle);
 textout(dc,0,0,pchar(s),length(s));
 releasedc(form1.edit1.handle,dc);
 end;
end;
constructor tmythread.create(myedit1:tedit);// 创建线程
begin
 inherited create(false);
 myedit:=myedit1;
 freeonterminate:=true; // 线程终止时自动删除对象,
end;
procedure thread1.show;// 类调用的线程函数
begin
 myedit.Text:=inttostr(count);
end;
procedure thread1.execute; // 线程方法重载
var
 i:integer;
begin
 for i:=0 to 100000 do
 begin
 count:=i;
 synchronize(show); // 线程调用同步
 end;
end;
procedure thread2.show;// 类调用的线程函数
begin
 mythreadfunc;
end;
procedure thread2.execute; // 线程方法重载
begin
 synchronize(show); // 线程调用同步
end;
procedure TForm1.class1buttonClick(Sender: TObject);// 引用类方法创
 建线程
begin
 with thread1.create(edit1) do
end;
procedure TForm1.class2buttonClick(Sender: TObject);
 // 引用类方法创
 建线程
begin
 with thread2.create(edit1) do
end;
procedure TForm1.routines1ButtonClick(Sender: TObject);
// 引用例程创建线程
var
hthread:thandle;
thid:dword;
begin
 hthread:=beginthread(nil,0,@mythreadfunc,nil,0,thid);
 if hthread=0 then
 showmessage(' 创建线程失败');
end;
procedure TForm1.routines2ButtonClick(Sender: TObject);
// 用例程创建线程失败
begin
mythreadfunc;
end;
end.
---- 点击“成功”按钮, 该应用程序成功的创建了一个线程, 在Edit1 框内不断计算数据的同时, 改变窗体的大小或移动窗体均能实现。而在点击“失败”按钮后, 会发现此应用程序中只能有一个主线程存在, 在程序没有计算完之前根本不能做其它任何事情!