首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Delphi 多线程编程(一)

2013-04-09 
Delphi 多线程编程(1)栈是私有的但堆是公用的, 如果不同的线程都来使用一个全局变量有点乱套为解决这个问

Delphi 多线程编程(1)




栈是私有的但堆是公用的, 如果不同的线程都来使用一个全局变量有点乱套;
为解决这个问题 Delphi 为我们提供了一个类似 var 的 ThreadVar 关键字, 线程在使用 ThreadVar 声明的全局变量时会在各自的栈中留一个副本, 这样就解决了冲突. 不过还是尽量使用局部变量, 或者在继承 TThread 时使用类的成员变量, 因为 ThreadVar 的效率不好, 据说比局部变量能慢 10 倍.

在下面的例子就测试了用 var 和 ThreadVar 定义变量的不同.
使用 var 效果图:
Delphi 多线程编程(一)
使用 ThreadVar 效果图:
Delphi 多线程编程(一)

能不能让它们别打架, 一个完了另一个再来? 这就要用到多线程的同步技术.
前面说过, 最简单的同步手段就是 "临界区".

先说这个 "同步"(Synchronize), 首先这个名字起的不好, 我们好像需要的是 "异步"; 其实异步也不准确...
管它叫什么名字呢, 它的目的就是保证不冲突、有次序、都发生.

"临界区"(CriticalSection): 当把一段代码放入一个临界区, 线程执行到临界区时就独占了, 让其他也要执行此代码的线程先等等; 这和前面用的 Lock 和 UnLock 差不多; 使用格式如下:


//WaitForSingleObject的示例代码文件:  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   hProcess: THandle; {进程句柄}  {等待一个指定句柄的进程什么时候结束} function MyThreadFun(p: Pointer): DWORD; stdcall; begin   if WaitForSingleObject(hProcess, INFINITE) = WAIT_OBJECT_0 then     Form1.Text := Format('进程 %d 已关闭', [hProcess]);   Result := 0; end;  {启动一个进程, 并建立新线程等待它的结束} procedure TForm1.Button1Click(Sender: TObject); var   pInfo: TProcessInformation;   sInfo: TStartupInfo;   Path: array[0..MAX_PATH-1] of Char;   ThreadID: DWORD; begin   {先获取记事本的路径}   GetSystemDirectory(Path, MAX_PATH);   StrCat(Path, '\notepad.exe');    {用 CreateProcess 打开记事本并获取其进程句柄, 然后建立线程监视}   FillChar(sInfo, SizeOf(sInfo), 0);   if CreateProcess(Path, nilnilnil, False, 0, nilnil, sInfo, pInfo) then   begin     hProcess := pInfo.hProcess;                           {获取进程句柄}     Text := Format('进程 %d 已启动', [hProcess]);      CreateThread(nil, 0, @MyThreadFun, nil, 0, ThreadID); {建立线程监视}   endend;  end.