明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

用Delphi編程時如何使用線程

[摘要]重 慶 郵 電 學 院 計 算 機 系 綜 合 微 機 室馬 英 杰 ---- Windows 95 是Microsoft 公 司 的 第 一 個 真 正 的 多 任 務 操 作 系 統(tǒng)。 在 每 一 時 刻 可 以有 多 個 進 程 同 時 工 作, 而 每 一 個 進 程 又 包 含 有 多 ...
重 慶 郵 電 學 院 計 算 機 系 綜 合 微 機 室

馬 英 杰

---- Windows 95 是Microsoft 公 司 的 第 一 個 真
正 的 多 任 務 操 作 系 統(tǒng)。 在 每 一 時 刻 可 以
有 多 個 進 程 同 時 工 作, 而 每 一 個 進 程 又 包 含 有 多 個 線
程。 但 只 有 一 個 處 理
器 的 計 算 機 不 可 能 真 正 地“ 同 時” 執(zhí) 行 多 個 線 程, 而
是 操 作 系 統(tǒng) 把 時 間 分 成
若 干 個 時 間 片, 然 后 把 一 個 個 時 間 片 分 配 給 每 一 個 線
程。

---- 一 個 執(zhí) 行 了 的 程 序 就 是 一 個 進
程, 一 個 進 程 則 至 少 有 一 個 主 線 程。 一 位
高 級 程 序 員, 絕 不 會 讓 自 己 的 程 序 里 面 只 有 一 個 主 線
程 存 在( 除 非 只 有 很
少 的 幾 十 行 代 碼), 而 是 盡 量 讓 自 己 的 程 序 在 同 一 時
刻 里 干 更 多 的 事, 在
比 較 大 一 點 的 應 用 中 尤 其 如 此, 象 數(shù) 據(jù) 庫 應 用 程 序,
在 統(tǒng) 計 的 時 候 我 還 想
做 其 他 事 呢 ! 因 此, 如 何 有 效 地 利 用 線 程 則 是 每 一 個
程 序 員 都 應 了 解 的。
本 文 就 此 簡 單 地 談 一 下 在Delphi 中 如 何 利 用 線 程。

---- ( 一) 當 使 用 線 程 時, 我 們 主 要 有
兩 個 任 務:

---- (1) 創(chuàng) 建 一 個 線 程。

---- (2) 創(chuàng) 建 一 個 能 作 為 線 程 入 口
的 函 數(shù)。

---- Windows API 調(diào) 用CreateThread 函 數(shù) 來 創(chuàng) 建
一 個 線 程。 函 數(shù) 如 下:

HANDLE CreateThread(LPSECURITY_
ATTRIBUTES  lpThreadAttributes,
//線程安全屬性地址
  DWORD  dwStackSize,
  //初始化線程堆棧尺寸
  LPTHREAD_START_ROUTINE  lpStartAddress,
  //線程函數(shù)所指向的地址
     LPVOID  lpParameter,
  //給線程函數(shù)傳遞的參數(shù)
  DWORD  dwCreationFlags,
  //有關(guān)線程的標志
  LPDWORD  lpThreadId
  //系統(tǒng)分配給線程的ID
     );

---- 第 一 個 參 數(shù) 是 安 全 屬 性, 一 般
設(shè) 為nil, 使 用 缺 省 的 安 全 屬 性。 當 我 們 想 此
線 程 有 另 外 的 子 進 程 時, 可 改 變 它 的 屬 性。

---- 第 二 個 參 數(shù) 是 線 程 堆 棧 尺 寸,
一 般 設(shè) 為0, 表 示 與 此 應 用 的 堆 棧 尺 寸 相
同, 即 主 線 程 與 創(chuàng) 建 的 線 程 一 樣 長 度 的 堆 棧。 并 且 其
長 度 會 根 據(jù) 需 要 自 動
變 長。

---- 第 三 個 參 數(shù), 也 是 最 重 要 的 一
個, 是 一 個 指 向 函 數(shù) 名 的 指 針, 但 傳 遞 時
很 簡 單, 只 需 在 線 程 函 數(shù) 名 前 加 上@ 就 可 以 了。

---- 第 四 個 參 數(shù) 是 你 需 要 向 線 程 函
數(shù) 傳 遞 的 參 數(shù), 一 般 是 一 個 指 向 結(jié) 構(gòu) 的 指
針。 不 需 傳 遞 參 數(shù) 時, 則 這 個 參 數(shù) 設(shè) 為nil。

---- 第 五 個 參 數(shù), 傳 入 與 線 程 有 關(guān)
的 一 些 標 志, 如 果 是CREATE_SUSPENDED, 則 創(chuàng) 建
一 個 掛 起 的 線 程, 即 這 個 線 程 本 身 已 創(chuàng) 建, 它 的 堆 棧
也 已 創(chuàng) 建。 但 這 個 線
程 不 會 被 分 配 給CPU 時 間, 只 有 當ResumeThread 函 數(shù) 被 調(diào) 用 后
才 能 執(zhí) 行; 當 然,
也 可 以 調(diào) 用SuspendThread 函 數(shù) 再 次 掛 起 線 程。 要 是 標 志 為0,
那 么 一 旦 建 立 線
程, 線 程 函 數(shù) 就 被 立 即 調(diào) 用。 一 般 傳 為0 即 可。

---- 最 后 一 個 參 數(shù) 是 系 統(tǒng) 分 配 給 這
個 線 程 的 唯 一 的ID 標 志。

---- 下 面 這 個 程 序MyThreadPro.pas 介 紹 了
線 程 如 何 建 立 及 使 用:

//Your first test Thread Program.
unit MyThreadPro;
interface
uses
  Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TForm1 = class(TForm)
    UsedThread: TButton;
    NoUsedThread: TButton;
    procedure UsedThreadClick(Sender: TObject);
    procedure NoUsedThreadClick(Sender: TObject);
var
  Form1: TForm1;
implementation
{$R *.DFM}
//這是線程函數(shù),
它可以放在下面程序的任何地方
function MyThreadFunc(P:pointer):Longint;stdcall;
var
   i:integer;
   DC:HDC;
   S:string;
begin
     DC:=GetDC(Form1.Handle);
     for i:=0 to 100000 do begin
         S:=Inttostr(i);
         Textout(DC,10,10,Pchar(S),length(S));
     end;
     ReleaseDC(Form1.Handle,DC);
end;
procedure TForm1.UsedThreadClick(Sender: TObject);
var
   hThread:Thandle;//定義一個句柄
   ThreadID:DWord;
begin
//創(chuàng)建線程,同時線程函數(shù)被調(diào)用
hthread:=CreateThread(nil,0,@MyThreadfunc,nil,0,ThreadID);
     if hThread=0 then
messagebox(Handle,'Didn’t Create a Thread',nil,MB_OK);
end;
procedure TForm1.NoUsedThreadClick(Sender: TObject);
begin
     MyThreadfunc(nil);
//沒有創(chuàng)建線程時,直接調(diào)用線程函數(shù)
end;
end.

---- 上 面 這 個 程 序 介 紹 了 我 們 在 使
用 線 程 及 未 使 用 線 程 二 種 情 況 下, 運 行 該
程 序 的 反 應。 當 點UsedThread 按 鈕 時, 則 建 立 一 個 線 程, 這
時 我 們 可 以 在 程 序
進 行 計 算 的 同 時, 改 變 窗 體 的 尺 寸 及 移 動 它。 當 按 下NoUsedThread
按 鈕 時, 不
建 立 線 程, 我 們 會 發(fā) 現(xiàn) 在 程 序 沒 有 計 算 完 之 前 根 本 不
能 做 其 它 任 何 事 情 !
此 程 序 在 基 于Windows 95 的Delphi 3 中 運 行 通 過。