每個線程擁有獨立的堆疊(Stack),用於儲存區域變數、函數呼叫鏈、參數傳遞等。dwStackSize 指定初始保留大小,單位位元組。
0:使用主線程相同大小(預設 1 MB),不足時自動擴展至記憶體上限。
| 特性 | Stack (堆疊) | Heap (堆) |
|---|---|---|
| 存取模式 | LIFO (後進先出) | 隨機存取 |
| 用途 | 區域變數、呼叫框架 | 動態記憶體分配 |
| 所有權 | 線程私有 | 進程共享 |
| 大小 | 固定上限 (可擴展) | 動態增長 |
| 效能 | 極快 (指針移動) | 較慢 (分配演算法) |
解決多線程共享全域變數衝突的 Delphi 語言級方案:
var
g_Counter: Integer; // 所有線程共享,需同步
g_ThreadCounter: Integer; // 錯誤示範:仍是共享
threadvar
tls_Counter: Integer; // 每個線程擁有獨立副本
使用 var (共享):三條線程同時遞增同一變數,輸出交織、數值衝突:

使用 threadvar (獨立):每條線程維護自己的計數器,互不干擾:

unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var Form1: TForm1;
implementation {$R *.dfm}
// var num: Integer; // 共享版本
threadvar num: Integer; // TLS 版本
function MyThreadFun(p: Pointer): DWORD; stdcall;
var py: Integer;
begin
py := Integer(p); // 參數傳遞 Y 座標
while True do
begin
Inc(num);
with Form1.Canvas do
begin
Lock;
TextOut(20, py, IntToStr(num));
Unlock;
end;
Sleep(1000);
end;
Result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var ID: DWORD;
begin
CreateThread(nil, 0, @MyThreadFun, Ptr(20), 0, ID);
CreateThread(nil, 0, @MyThreadFun, Ptr(40), 0, ID);
CreateThread(nil, 0, @MyThreadFun, Ptr(60), 0, ID);
end;
end.
TThread 時使用類別成員欄位(每個線程實例獨立)threadvarthreadvar 變數在線程啟動時自動初始化為 0/nil,線程結束時自動終結 (釋放介面、字串、動態陣列等)。// 呼叫端
num := MakeLong(X, Y); // 低 16-bit = X, 高 16-bit = Y
CreateThread(nil, 0, @MyThreadFun, Ptr(num), 0, ID);
// 線程端
x := LoWord(Integer(p));
y := HiWord(Integer(p));
// 或無 API 版本:
// x := Integer(p) and $FFFF;
// y := Integer(p) shr 16;
這正是 Windows 訊息 lParam 傳遞滑鼠座標的經典做法。