(1)创建线程
MsgThread := TMsgThread.Create(False) ;    //创建并执行线程
MsgThread := TMsgThread.Create(True) ;   //创建线程后挂起
constructor Create(CreateSuspended: Boolean); 中的参数CreateSuspended表示创建后是否挂起线程。
(2)设置线程里没有设置循环执行的话,且设置FreeOnTerminate为True,则线程执行完后就会自己释放。
(3)在一个线程结束后,调用另一个事件的方法:
只要设置Onterminate:=某方法,这样在线程结束前自然会被调用,比如 :
procedure TSendShortMessageThread.Execute;
var
 Bitmap: Tbitamp;
begin
Bimap:=Tbitmap.create(nil) ;
OnTerminate:=Threaddone;
end;

procedure Threaddone(sender: tobject);
begin
Bimap.Free;   //在Destory之前会被调用
end;
(4)程序结束前安全的退出线程的方法:
     if MsgThread <> nil then
   begin
     MsgThread.Terminate ;
     MsgThread.WaitFor ;
   end;
(5)判断当前线程的状态:
//以下资料来自大富翁论坛。
/判断线程是否释放
//返回值:0-已释放;1-正在运行;2-已终止但未释放;
//3-未建立或不存在
function TFrmMain.CheckThreadFreed(aThread: TThread): Byte;
var
 i: DWord;
 IsQuit: Boolean;
begin
 if Assigned(aThread) then
 begin
   IsQuit := GetExitCodeThread(aThread.Handle, i);
   if IsQuit then           //If the function succeeds, the return value is nonzero.
                                 //If the function fails, the return value is zero.
   begin
     if i = STILL_ACTIVE then    //If the specified thread has not terminated,
                                 //the termination status returned is STILL_ACTIVE.
       Result := 1
     else
       Result := 2;              //aThread未Free,因为Tthread.Destroy中有执行语句
   end
   else
     Result := 0;                //可以用GetLastError取得错误代码
 end
 else
   Result := 3;
end;
(6)线程同步。
如果线程要调用VCL里面的内容(如:别的窗体中的控件),就需要将这个线程同步。线程同步表示交由主线程运行这段代码,各个线程都在主线程中分时间段运行。另外,要想避免多个线程同时执行同一段代码也需要将多线程同步。
临界区和互斥的作用类似,都是用来进行同步的,但它们间有以下一点差别:
临界区只能在进程内使用,也就是说只能是进程内的线程间的同步;而互斥则还可用在进程之间的;临界区所花消的时间很少,才10~15个时间片,而互斥需要400多个;临界区随着进程的终止而终止,而互斥,如果你不用closehandle()的话,在进程终止后仍然在系统内存在,也就是说它是系统全局对象;
同步的方法有:

(1)使用临界区对象。
临界区对象有两种:TRTLCriticalSection 和 CriticalSection。
  TRTLCriticalSection的用法

var
 GlobalVariable:Double;

var
 CriticalSection:TRTLCriticalSection;

procedure SetGlobalVariable(Value:Double);
begin
 EnterCriticalSection(CriticalSection);   //进入临界区
 try
   GlobalVariable:=Value;
 finally
   LeaveCriticalSection(CriticalSection);  //离开临界区
 end;
end;

initialization
 InitializeCriticalSection(CriticalSection);  //初始化
finalization
 DeleteCriticalSection(CriticalSection); //删除
end.
  CriticalSection(重要区段)的用法:
var criticalsection: TCriticalsection;
创建:criticalsection := TCriticalsection.create;
使用:
criticalsection.enter;
try
  ...
finally
  criticalsection.leave;
end;    

   (2)使用互斥
先在主线程中创建事件对象:
var
  hMutex: THandle = 0;
  ...
 hMutex := CreateMutex(nil, False, nil);

 在线程的Execute方法中加入以下代码:
if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then
  //Do Something;
  ...
ReleaseMutex(hMutex);

最后记得要释放互斥对象:
CloseHandle(hMutex);

(3)使用信号量

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TMyThread = class(TThread)
  private

  protected
    procedure Execute; override;
  public

    constructor Create; virtual;
  end;

var
  Form1 : TForm1;
  HSem : THandle = 0 ;
implementation

{$R *.dfm}

var
  tick: Integer = 0;
procedure TMyThread.Execute;
var
  WaitReturn : DWord ;
begin
  WaitReturn := WaitForSingleObject(HSem,INFINITE) ;
  Form1.Edit1.Text := IntToStr(tick);
  Inc(tick);
  Sleep(10);
  ReleaseSemaphore(HSem, 1, Nil)
end;

constructor TMyThread.Create;
begin
  inherited Create(False);
  FreeOnTerminate := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  HSem := CreateSemaphore(Nil,1,1,Nil) ;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CloseHandle(HSem) ;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  index: Integer;
begin
  for index := 0 to 10 do
  begin
    TMyThread.Create;
  end;
end;

end.
一般的同步对象使用Mutex对象,是因为Mutex有一个特别之处:当一个持有对象的线程DOWN掉的时候,mutex对象可以自动让其它等待这个对象的线程接受,而其它的内核对象则不具体这个功能。
之所要使用Semaphore则是因为Semaphore可以提供一个活动线程的上限,即lMaximumCount参数,这才是它的真正有用之处。

image Delphi 多线程安全动态库 dll   src="http://blog.csdn.net/count.aspx?ID=1782020&Type=Rank">image  image

Delphi 可以快速开发桌面程序,用来做dll 封装操作,封装窗体都是很方便的。
在 delphi 做动态库时,会自动提示要 uses ShareMem,这个实际用起来是不方便的,因为 dll 可能要发布,要给其他人用,而别人用什么语言来开发是说不准的,如果不是delphi,就没办法用了。因此在接口上一般是用 pchar来代替string。但是在内部,string 还是可以拿来用的。

这样就会产生一个问题,如果动态库是支持多线程来用的,而在动态库内部并没有显式的创建一个线程时,烦繁使用 string 就说不定什么时候会产生一个内存出错。

在Delphi 内部,定义了一个 isMultiThread 的boolean 型全局变量(好象是在 system 单元)。默认这个变量是 false的。当显示地创建一个线程时(如TThread.Create),会置成true。否则一直是false。
这个变量唯一使用的地方是在 GetMem 和 FreeMem时,如果为 True,会先进入临界区,操作完成后退出。如果为false就没有临界区了。

因此在编写多线程安全的动态库时,一定要记得在动态库初始化的时候手动加上 isMultiThread=true; 这样强制delphi来使用临界区操作。

如果调用程序也是用 delphi 来写的,可能会多线程使用,那最好也在初始化的时候加上这句。值得注意的是,调用程序和动态库的这两个变量是两个互不相干的,也就是两边都得加,只在一方加上是影响不了另一方的。

其他有关多线程安全的就是一些常识了,对可能多线程访问的代码,要用事件,信号量,临界区等方法加以保护。使用方法可以参考delphi的帮助文档,或msdn,或网上的大堆文章。