多线程编程(5) - 从 CreateThread 说起[续三]


function CreateThread(

  lpThreadAttributes: Pointer;

  dwStackSize: DWORD;

  lpStartAddress: TFNThreadStartRoutine; {入口函数的指针}

  lpParameter: Pointer; 

  dwCreationFlags: DWORD;

  var lpThreadId: DWORD

): THandle; stdcall;


 
   

到了入口函数了, 学到这个地方, 我查了一个入口函数的标准定义, 这个函数的标准返回值应该是 DWORD, 不过这函数在 Delphi 的 System 单元定义的是: TThreadFunc = function(Parameter: Pointer): Integer; 我以后会尽量使用 DWORD 做入口函数的返回值.

这个返回值有什么用呢?
等线程退出后, 我们用 GetExitCodeThread 函数获取的退出码就是这个返回值!

如果线程没有退出, GetExitCodeThread 获取的退出码将是一个常量 STILL_ACTIVE (259); 这样我们就可以通过退出码来判断线程是否已退出.

还有一个问题: 前面也提到过, 线程函数不能是某个类的方法! 假如我们非要线程去执行类中的一个方法能否实现呢?
尽管可以用 Addr(类名.方法名) 或 MethodAddress('published 区的方法名') 获取类中方法的地址, 但都不能当做线程的入口函数, 原因可能是因为类中的方法的地址是在实例化为对象时动态分配的.
后来换了个思路, 其实很简单: 在线程函数中再调用方法不就得了, 估计 TThread 也应该是这样.

下面的例子就尝试了用线程调用 TForm1 类中的方法, 并测试了退出码的相关问题.

本例效果图:

多线程编程(5) - 从 CreateThread 说起[续三]

代码文件:

unit Unit1;



interface



uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls;



type

  TForm1 = class(TForm)

    Button1: TButton;

    Button2: TButton;

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    private

      procedure FormProc; {准备给线程使用的方法}

  end;



var

  Form1: TForm1;



implementation



{$R *.dfm}



var

  hThread: THandle;



{线程入口函数}

function MyThreadFun(p: Pointer): DWORD; stdcall;

begin

  Form1.FormProc; {调用 TForm1 类的方法}

  Result := 99;   {这个返回值将成为线程的退出代码, 99 是我随意给的数字}

end;



{TForm1 的方法, 本例中是给线程的入口函数调用的}

procedure TForm1.FormProc;

var

  i: Integer;

begin

  for i := 0 to 200000 do

  begin

    with Form1.Canvas do begin

      Lock;

      TextOut(10, 10, IntToStr(i));

      Unlock;

    end;

  end;

end;



{建立并执行线程}

procedure TForm1.Button1Click(Sender: TObject);

var

  ID: DWORD;

begin

  hThread := CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);

end;



{获取线程的退出代码, 并判断线程是否退出}

procedure TForm1.Button2Click(Sender: TObject);

var

  ExitCode: DWORD;

begin

  GetExitCodeThread(hThread, ExitCode);



  if hThread = 0 then

  begin

    Text := '线程还未启动';

    Exit;

  end;



  if ExitCode = STILL_ACTIVE then

    Text := Format('线程退出代码是: %d, 表示线程还未退出', [ExitCode])

  else

    Text := Format('线程已退出, 退出代码是: %d', [ExitCode]);

end;



end.


 
   

窗体文件:

object Form1: TForm1

  Left = 0

  Top = 0

  Caption = 'Form1'

  ClientHeight = 84

  ClientWidth = 376

  Color = clBtnFace

  Font.Charset = DEFAULT_CHARSET

  Font.Color = clWindowText

  Font.Height = -11

  Font.Name = 'Tahoma'

  Font.Style = []

  OldCreateOrder = False

  PixelsPerInch = 96

  TextHeight = 13

  object Button1: TButton

    Left = 183

    Top = 32

    Width = 75

    Height = 25

    Caption = 'Button1'

    TabOrder = 0

    OnClick = Button1Click

  end

  object Button2: TButton

    Left = 280

    Top = 32

    Width = 75

    Height = 25

    Caption = 'Button2'

    TabOrder = 1

    OnClick = Button2Click

  end

end


 
   

你可能感兴趣的:(thread)