1、臨界區(qū)
一次只能由一個(gè)線程來(lái)執(zhí)行的一段代碼。
2、互斥
互斥非常類(lèi)似于臨界區(qū),除了兩個(gè)關(guān)鍵的區(qū)別:首先,互斥可用于跨進(jìn)程的線程同步。其次,互斥能被賦予一個(gè)字符串名字,并且通過(guò)引用此名字創(chuàng)建現(xiàn)有互斥對(duì)象的附加句柄。
臨界區(qū)與事件對(duì)象(如互斥對(duì)象)的最大區(qū)別是在性能上。臨界區(qū)在沒(méi)有線程沖突時(shí),要用10-15個(gè)時(shí)間片,而事件對(duì)象由于涉及到系統(tǒng)內(nèi)核要用400-600個(gè)時(shí)間片。
3、信號(hào)量
它是在互斥的基礎(chǔ)上建立的,但信號(hào)量增加了資源計(jì)數(shù)的功能,預(yù)定數(shù)目的線程允許同時(shí)進(jìn)入要同步的代碼。
{*******************************************************}
{ }
{ 多線程同步演示代碼 }
{ }
{ 版權(quán)所有 (C) 2010 風(fēng)林 }
{ }
{*******************************************************}
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; //臨界區(qū)記錄
hMutex:THandle = 0; //互斥句柄
hSem:THandle = 0;//信號(hào)量句柄
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; //線程結(jié)束時(shí)執(zhí)行相應(yīng)清理代碼
FreeOnTerminate := True; //自動(dòng)釋放資源
//EnterCriticalSection(CS); //進(jìn)入臨界區(qū)
WaitReturn := WaitForSingleObject(hSem,INFINITE);//計(jì)數(shù)器減1
// if WaitForSingleObject(hMutex,INFINITE)= WAIT_OBJECT_0 then
if WaitReturn = WAIT_OBJECT_0 then
begin
SetShowStr(FNewStr);
SetShowStr('');
Sleep(100);
end;
//LeaveCriticalSection(CS);//離開(kāi)臨界區(qū)
// ReleaseMutex(hMutex); //解除擁有關(guān)系,互斥對(duì)象重新進(jìn)入發(fā)信號(hào)狀態(tài)
ReleaseSemaphore(hSem,1,nil);//信號(hào)量對(duì)象計(jì)數(shù)加1
end;
procedure TForm1.btnStartClick(Sender: TObject);
begin
// InitializeCriticalSection(CS);//初始化臨界區(qū)
// hMutex := CreateMutex(nil,False,nil); //創(chuàng)建一個(gè)互斥量
hSem := CreateSemaphore(nil,
1, //這個(gè)值必須在0和lMaximumCount之間,大于0則表示處理發(fā)信號(hào)狀態(tài)
1, //由于只允許個(gè)線程進(jìn)入同步代碼,所以設(shè)置成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 //當(dāng)前測(cè)試時(shí)創(chuàng)建了3個(gè)線程
begin
// DeleteCriticalSection(CS); //刪除臨界區(qū)記錄信息
//CloseHandle(hMutex);//釋放由CreateMutex創(chuàng)建對(duì)象的句柄
CloseHandle(hSem);//釋放由CreateSemaphore創(chuàng)建對(duì)象的句柄
end;
end;
end.