トップへ(mam-mam.net/)

Parallel Programming with the TTask Class — Delphi Source Code Collection

Japanese

Parallel Programming with the TTask Class — Delphi Source Code Collection

This article explains how to use the TTask class in Delphi for parallel programming, using a sample source code that performs prime number detection.
In this example, 100 TTask instances are used to run prime checks in 100-way parallel execution.

Screen Layout

Launch the Delphi IDE and select "File" => "Windows VCL Application – Delphi" to create a new project and its initial form.
From the "Palette" pane in the lower-right corner, drag and drop the following components onto the form:

s

Writing the Source Code

Press F12 to switch to the Code Editor, then copy and paste the following source code.
Press F12 again to return to the Form Designer, open the [Events] tab in the Object Inspector at the lower-left pane, select Button1, and set Button1.OnClick to Button1Click.

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  System.Threading, System.SyncObjs, System.Math;

type

  // Using the TTask class from the parallel programming library
  // If Num is a prime number, add the result to fAnswers
  TPrimeTest=class(TTask, ITask)
  private
    fNum:INT64;
    fAnswers:TStringList;
  public
    constructor Create(Num:Int64; Answers:TStringList);
    procedure TaskStart;
  end;


  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TPrimeTest }

constructor TPrimeTest.Create(Num: Int64; Answers: TStringList);
begin
  //Store parameters in private fields
  fNum:=Num;
  fAnswers:=Answers;
  //Call the parent class constructor
  inherited Create(
    nil, nil,
    procedure
    begin
      Self.TaskStart;
    end,
    nil, nil, []
  );
end;

procedure TPrimeTest.TaskStart;
var i,m:Int64;
    flag:Boolean;
    st:String;
begin
  st:='';
  if fNum<2 then
  begin
    exit;
  end
  else if (fNum=2) or (fNum=3) then
  begin
    st:=Format('%d is a prime number',[fNum]);
  end
  else
  begin
    m:=Trunc(Sqrt(fNum));
    i:=2;
    flag:=True;
    while i<=m do
    begin
      if fNum Mod i =0 then
      begin
        flag:=False; //Not a prime number
        break;
      end;
      inc(i);
    end;
    if flag then
      st:=Format('%d is a prime number',[fNum]);
  end;

  if st<>'' then
  begin
    //Protect shared object access (lock)
    System.MonitorEnter(fAnswers);
    try
      // Add result to the list
      fAnswers.Add(st);
    finally
      //Release lock
      System.MonitorExit(fAnswers);
    end;
  end;
end;

{TForm1}

procedure TForm1.Button1Click(Sender: TObject);
const
    //Execute up to 100 tasks in parallel
    MaxTaskCount:Integer = 100;
    //Find prime numbers between 10000 and 50000
    FromNumber:Integer=10000;
    ToNumber  :Integer=50000;
var i,n:Int64;
    Tasks:TArray<ITask>;
    TaskCount:Integer;
    Answers:TStringList;
begin
  Memo1.ScrollBars:=ssBoth;
  Answers:=TStringList.Create;
  try
    n:=FromNumber;
    while n<=ToNumber do
    begin

      if (n+MaxTaskCount-1)>ToNumber then
        TaskCount:=ToNumber-n+1
      else
        TaskCount:=MaxTaskCount;

      //Prepare tasks for parallel execution
      SetLength(Tasks,TaskCount);
      for i := Low(Tasks) to High(Tasks) do
      begin
        Tasks[i]:=TPrimeTest.Create(n,Answers) as ITask;
        inc(n);
      end;

      //Start all tasks
      for i := Low(Tasks) to High(Tasks) do Tasks[i].Start;

      // Wait until all tasks are completed
      // The order of start and completion is not guaranteed
      TTask.WaitForAll(Tasks);
    end;

    //Memo1.Lines.BeginUpdate;
    Memo1.Lines.Assign(Answers);
    //Memo1.Lines.EndUpdate;
  finally
    Answers.Free;
  end;
end;

end.

Running the Program

Click the Run button in the IDE to start the application.
When you click Button1, the program will search for prime numbers between 10,000 and 50,000 and display the results in Memo1.