在是使用TThread时将会用到Classes单元中定义的9个函数,这9个函数为TThread提供同步管理
下面就来分析一下,这几个函数,在函数中用到的几个单元变量
var
SyncList: TList = nil;//统计同时调用同步方法的线程对象
ThreadLock: TRTLCriticalSection;
ThreadCount: Integer;//统计进程中的线程数量
1.InitThreadSynchronization
这个函数功能是初始化临界区和创建事件对象
procedure InitThreadSynchronization;
begin
InitializeCriticalSection(ThreadLock);//初始化临界区
SyncEvent := CreateEvent(nil, True, False, '');//创建事件对象
if SyncEvent = 0 then
RaiseLastOSError;
end;
2.DoneThreadSynchronization
这个函数的功能是销毁同步对象
procedure DoneThreadSynchronization;
begin
DeleteCriticalSection(ThreadLock);//删除临界区
CloseHandle(SyncEvent);//关闭事件对象
end;
3.ResetSyncEvent
将SyncEvent置为无信号状态
procedure ResetSyncEvent;
begin
ResetEvent(SyncEvent);
end;
4.WaitForSyncEvent(Timeout: Integer);
在一定时间内,如果SyncEvent为有信号状态Reset SyncEvent
procedure WaitForSyncEvent(Timeout: Integer);
begin
if WaitForSingleObject(SyncEvent, Timeout) = WAIT_OBJECT_0 then
ResetSyncEvent;
end;
5.SignalSyncEvent
置SyncEvent为有信号状态
procedure SignalSyncEvent;
begin
SetEvent(SyncEvent);
end;
6.AddThread
将ThreadCount加1,原子执行
procedure AddThread;
begin
InterlockedIncrement(ThreadCount);
end;
7.RemoveThread
将ThreadCount减1,原子执行
procedure RemoveThread;
begin
InterlockedDecrement(ThreadCount);
end;
8.CheckSynchronize
主线程对子线程同步,使得在多个子线程同时执行同步方法时,以循环的方式执行,只能在主线程中调用(1)
主线程只有一个,子线程有多个,多个子线程同时调用同步方法是需要进行同步,用一个TList对象保存这写对象
在TApplication.idle中被调用
function CheckSynchronize(Timeout: Integer = 0): Boolean;
var
SyncProc: PSyncProc;
LocalSyncList: TList;
begin
if GetCurrentThreadID <> MainThreadID then//(1)不是主线程就扔出一个异常
raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);
if Timeout > 0 then
WaitForSyncEvent(Timeout)
else
ResetSyncEvent;//所有等待线程将停止执行,
LocalSyncList := nil;
EnterCriticalSection(ThreadLock);//进入临界区,对SyncList和LocalSyncList进行保护,;
try
Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));
// 交换Integer(SyncList), Integer(LocalSyncList));
try
Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
if Result then
begin
while LocalSyncList.Count > 0 do
begin
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
LeaveCriticalSection(ThreadLock);
try
try
SyncProc.SyncRec.FMethod;//执行同步方法
except
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
end;
finally
EnterCriticalSection(ThreadLock);
end;
SetEvent(SyncProc.signal);
end;
end;
finally
LocalSyncList.Free;
end;
finally
LeaveCriticalSection(ThreadLock);
end;
end;
9.线程函数,在CreateThread中将会使用,此函数间会调用Thread.Execute;
function ThreadProc(Thread: TThread): Integer;
var
FreeThread: Boolean;
begin
try
if not Thread.Terminated then
try
Thread.Execute;
except
Thread.FFatalException := AcquireExceptionObject;
end;
finally
FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.DoTerminate;
Thread.FFinished := True;
SignalSyncEvent;
if FreeThread then Thread.Free;
EndThread(Result);
end;
end;