1、臨界區
一次只能由一個線程來執行的一段代碼。
2、互斥
互斥非常類似于臨界區,除了兩個關鍵的區別:首先,互斥可用于跨進程的線程同步。其次,互斥能被賦予一個字符串名字,并且通過引用此名字創建現有互斥對象的附加句柄。
臨界區與事件對象(如互斥對象)的最大區別是在性能上。臨界區在沒有線程沖突時,要用10-15個時間片,而事件對象由于涉及到系統內核要用400-600個時間片。
3、信號量
它是在互斥的基礎上建立的,但信號量增加了資源計數的功能,預定數目的線程允許同時進入要同步的代碼。

{*******************************************************}
{                                                       }
{       多線程同步演示代碼                              }
{                                                       }
{       版權所有 (C) 2010 風林                          }
{                                                       }
{*******************************************************}


unit untMain;

interface

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

type
  TForm1 = class(TForm)
    btnStart: TButton;
    procedure btnStartClick(Sender: TObject);
  private
    procedure ThreadsDone(Sender:TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
var
  CS:TRTLCriticalSection; //臨界區記錄
  hMutex:THandle = 0; //互斥句柄
  hSem:THandle = 0;//信號量句柄
  DoneFlags:Integer = 0;
threadvar//線程局部變量
  GlobalStr:string;
type
  TTLSThread = class(TThread)
    private
      FNewStr:string;
    protected
      procedure Execute;override;
    public
      constructor Create(const ANewStr:string);
  end;

procedure SetShowStr(const S:string);
begin
  if S = '' then
    MessageBox(0,PChar(GlobalStr),'The string is...',MB_OK)
  else
    GlobalStr := S; 
end;

{ TTLSThread }

constructor TTLSThread.Create(const ANewStr: string);
begin
  FNewStr := ANewStr;
  inherited Create(False);
end;

procedure TTLSThread.Execute;
var
  WaitReturn:DWORD;
begin
  OnTerminate := Form1.ThreadsDone; //線程結束時執行相應清理代碼
  FreeOnTerminate := True; //自動釋放資源
  //EnterCriticalSection(CS); //進入臨界區
  WaitReturn := WaitForSingleObject(hSem,INFINITE);//計數器減1
//  if WaitForSingleObject(hMutex,INFINITE)= WAIT_OBJECT_0 then
  if WaitReturn = WAIT_OBJECT_0  then
  begin
    SetShowStr(FNewStr);
    SetShowStr('');
    Sleep(100);
  end;
  //LeaveCriticalSection(CS);//離開臨界區
//  ReleaseMutex(hMutex); //解除擁有關系,互斥對象重新進入發信號狀態
  ReleaseSemaphore(hSem,1,nil);//信號量對象計數加1
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
//  InitializeCriticalSection(CS);//初始化臨界區
//  hMutex := CreateMutex(nil,False,nil); //創建一個互斥量
  hSem := CreateSemaphore(nil,
    1, //這個值必須在0和lMaximumCount之間,大于0則表示處理發信號狀態
    1, //由于只允許個線程進入同步代碼,所以設置成1
    nil);//
  SetShowStr('Hello world');
  TTLSThread.Create('Dilbert');
  TTLSThread.Create('xx');
  TTLSThread.Create('test');
end;

procedure TForm1.ThreadsDone(Sender: TObject);
begin
  Inc(DoneFlags);
  if DoneFlags = 3 then  //當前測試時創建了3個線程
  begin
   // DeleteCriticalSection(CS); //刪除臨界區記錄信息
   //CloseHandle(hMutex);//釋放由CreateMutex創建對象的句柄
   CloseHandle(hSem);//釋放由CreateSemaphore創建對象的句柄
  end;
end;

end.