TLightweightSemaphore (Delphi)

From RAD Studio Code Examples
Jump to: navigation, search

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]

Uses