一、线程的局部变量threadvar

type   TForm1 = class(TForm)     Button1: TButton;     Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;   TMyThread=class(TThread) private     FNewStr:string; protected procedure Execute;override; public constructor Create(const ANewStr:string); end; var   Form1: TForm1; implementation {$R *.dfm} var   n:integer; threadvar   GlobalStr:string; procedure SetShowStr(const S:string;Memo:TMemo); begin if s=” then //MessageBox(0,pchar(GlobalStr),’The String is…’,MB_OK) begin     inc(n);     Memo.Lines.Add(inttostr(n)+GlobalStr); end else  GlobalStr:=S; end; constructor TMyThread.Create(const ANewStr: string); begin   FNewStr:=ANewStr;   Inherited Create(False); end; procedure TMyThread.Execute; begin   FreeOnTerminate:=True; //终止后自动free   SetShowStr(FnewStr, Form1.Memo1);   SetShowStr(”, Form1.Memo1); end; procedure TForm1.Button1Click(Sender: TObject); begin   n:=1;   SetShowStr(‘Hello World’, Form1.Memo1);   //Global:=’Hello World’   SetShowStr(”, Form1.Memo1);    //show 1Global   TMyThread.Create(‘Mygodsos’);  //Global:=’Mygodsos’,show 2Global   Sleep(100);   SetShowStr(”, Form1.Memo1);  //show 3Global  end; end.

当GlobalStr 声明不同时,结果分别是:

Threadvar var

1Hello World 1Hello World

3Hello World 3Mygodsos

2Mygodsos 2Mygodsos

Delphi利用关键字threadvar封装API线程局部存储。它能使你在第一个运行的线程中创建一个全局变量的拷贝。如果用ThreadVar声明变量,则在程序结束前必须手动释放其占用的空间(这个手动释放的问题不知道d2007解决没有?)

(ps 我看到很多关于threadvar释放要 := ”的,若不是string类型的给如何释放?)

二、双线程看看Threadvar:

把Execute()里Create(False)改成Create(True)

procedure TForm1.Button2Click(Sender: TObject); var   MyThread1:TMyThread;   MyThread2:TMyThread; begin   n:=0;   SetShowStr(‘Hello World’,Form1.Memo1);   //Global:=’Hello World’   SetShowStr(”,Form1.Memo1);    //show Global   MyThread1:=TMyThread.Create(‘thread 1:’);  //Global:=’Mygodsos’,show Global   MyThread2:=TMyThread.Create(‘thread 2:’);  //Global:=’Mygodsos’,show Global   MyThread1.Resume;   MyThread2.Resume;   Sleep(100);   SetShowStr(”,Form1.Memo1);  //show Global end;

当GlobalStr 声明为不同,结果对比是:

Threadvar Var

1Hello World 1Hello World

4Hello World 4thread 2:

2thread 1: 3thread 2:

3thread 2: 2thread 1:

这里出现一个十分有趣的问题,若sleep()位置不同,结果不一样。

MyThread1.Resume;

Sleep(100);

MyThread2.Resume;

//Sleep(100);

改成这样后,结果是:

Threadvar Var

1Hello World 1Hello World

3Hello World 3thread 1:

2thread 1: 2thread 1:

4thread 2: 4thread 2:

留意一下前面的序号,似乎sleep()的作用比较奇怪。

三、Sleep()函数

Win32API过程Sleep()。此过程声明如下:

procedure Sleep(dwMilliseconds:DWORD); stdcall;

Sleep()过程用来告诉操作系统,当前的线程在参数dwMilliseconds指定的时间内不需要分配任何CPU时间。插入这个调用是使很多的任务在发生时,使执行哪个线程有一些随机性。通常,可以把参数dwMilliseconds设为0。尽管,这并没有使当前的线程真的“睡眠”,但它使操作系统把CPU时间分给了其他优先级相等或更高的线程。要小心Sleep()神秘的时间调整问题。Sleep()可能会使你的机器出现特别的问题。这种问题在另一台机器上可能无法再现。

对上面的例子,改回以下,把global设成var声明:

MyThread1.Resume;

MyThread2.Resume;

Sleep(100);

执行几次,结果:

1Hello World 1Hello World

4thread 2: 4thread 2:

3thread 2: 2thread 1:

2thread 1: 3thread 2:

看来sleep后,在主进程中先返回哪个线程是有一定的随机性的。但前面的序号还是一样的,意思是虽然主进程返回哪个线程的次序不一样,但线程执行的次序还是没变。不知道我这样理解对不对。