程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 多線程編程(5) - 從 CreateThread 說起[續三]

多線程編程(5) - 從 CreateThread 說起[續三]

編輯:Delphi

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



 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved