免费自己制作网站方法wordpress网站建设
如果对象不提供内置的锁定机制,则可以使用临界区。临界区的工作方式类似于允许单个线程在任何时刻进入的门。要使用临界区,创建一个 System.SyncObjs.TCriticalSection
的全局实例。System.SyncObjs.TCriticalSection
有两个方法:Acquire
(用于阻止其他线程执行该区域)和 Release
(用于解除阻塞)。
每个临界区都与您想要保护的全局内存相关联。每个访问该全局内存的线程在访问之前都应首先使用 Acquire
方法,以确保没有其他线程正在使用它。当完成后,线程调用 Release
方法,以便其他线程可以通过调用 Acquire
访问全局内存。
警告:临界区仅在每个线程都使用它们来访问关联的全局内存时才有效。如果线程忽略临界区并在不调用 Acquire
的情况下访问全局内存,可能会引入同时访问的问题。
例如,考虑一个应用程序,它有一个全局临界区变量 LockXY
,用于阻止对全局变量 X
和 Y
的访问。任何使用 X
或 Y
的线程都必须在访问之前调用临界区方法,如下所示:
LockXY.Acquire; // 请求临界区
try // 访问全局变量 X 和 Y
finally LockXY.Release; // 释放临界区
end;
举例如下:
program SleepSortDemo;{$APPTYPE CONSOLE}usesWindows, SysUtils, Classes, SyncObjs;typeTSleepThread = class(TThread)privateFValue: Integer;FLock: TCriticalSection;protectedconstructor Create(AValue: Integer; ALock: TCriticalSection);procedure Execute; override;end;constructor TSleepThread.Create(AValue: Integer; ALock: TCriticalSection);
beginFValue := AValue;FLock := ALock;inherited Create(False);
end;procedure TSleepThread.Execute;
beginSleep(1000 * FValue);FLock.Acquire;Write(FValue:3);FLock.Release;
end;constArrLen = 16;varA: array [0 .. ArrLen - 1] of Integer;Handles: array [0 .. ArrLen - 1] of THandle;Threads: array [0 .. ArrLen - 1] of TThread;Lock: TCriticalSection;I: Integer;begin// Generate random datafor I := 0 to ArrLen - 1 dobeginA[I] := Random(ArrLen - 1);Write(A[I]:3);end;Writeln;// Create critical section and threadsLock := TCriticalSection.Create;for I := 0 to ArrLen - 1 dobeginThreads[I] := TSleepThread.Create(A[I], Lock);Handles[I] := Threads[I].Handle;end;// Wait until threads terminate// This may take up to ArrLen - 1 secondsWaitForMultipleObjects(ArrLen, @Handles, True, INFINITE);// Destroy thread instancesfor I := 0 to ArrLen - 1 doThreads[I].Free;Lock.Free;Writeln;Readln;end.