TLightweightSemaphore (Delphi)
Description
The following example illustrates the use of the TLightweightSemaphore class. (You can actually use here the TSemaphore class instead of TLightweightSemaphore, with minor code modifications.)
Three threads are created. Each of them is trying to write in the console the (approximate) execution time interval (start and end). The console, in this case, is the critical resource. The semaphore that is created to coordinate the write operations is initialized with value 1 (which means that it behaves like a mutex). You may see that the intervals displayed do not overlap, which indicates that the threads are synchronized when writing in to the console.
Code
program TLightweightSemaphore_example;
{$APPTYPE CONSOLE}
uses
SysUtils, SyncObjs, Classes, DateUtils;
const
TimeStep = 100; { Milliseconds }
var
ConsoleSemaphore: TLightweightSemaphore;
type
TThreadConsumer = class(TThread)
private
procedure Execute; override;
end;
function SecondsAndMilliseconds(DateTime: TDateTime): string;
begin
Result := IntToStr(SecondOf(DateTime)) + ':' + IntToStr(MilliSecondOf(DateTime));
end;
procedure TThreadConsumer.Execute;
begin
ConsoleSemaphore.WaitFor();
Write('[' + SecondsAndMilliseconds(Time));
Sleep(TimeStep);
Writeln('; ' + SecondsAndMilliseconds(Time) + ']');
ConsoleSemaphore.Release();
end;
var
I: Integer;
Consumer: array [1 .. 3] of TThreadConsumer;
begin
ConsoleSemaphore := TLightweightSemaphore.Create(1);
{ Start threads. }
for I := Low(Consumer) to High(Consumer) do
begin
Consumer[I] := TThreadConsumer.Create(True);
Consumer[I].Start;
end;
{ Sleep until all the threads are certainly finished. }
Sleep(2 * ( High(Consumer) - Low(Consumer)) * TimeStep);
end. { Put breakpoint here to see the console output. }
Sample console output
[29:405; 29:499] [29:499; 29:593] [29:593; 29:702]