Home » Tutorials » Object Pascal/RTL » Parallelisierung mit Delphis Parallel Library

Parallelisierung mit Delphis Parallel Library

Parallele Tasks ausführen

Nun möchte man vielleicht nicht nur Schleifen parallel ausführen können, sonderen beliebigen Code. Solche Code-Einheiten, die parallel ausgeführt werden können, werden „Task“ genannt. Dazu passend gibt es die Klasse System.Threading.TTask. Über eine anonyme Methode wird der auszuführende Code angegeben, wie schon bei der parallelen For-Schleife:

var MyTask: ITask;
begin
  MyTask := TTask.Create(procedure()
    begin
      // Do something
    end;
  );
  MyTask.Start;

Die Ausführung des Tasks beginnt, sobald die Methode Start aufgerufen wird.

Möchte man mehrere verschiedene Tasks definieren, bietet es sich an, diese in einem Array abzulegen. Dann ist es nämlich ganz einfach, am Ende der Methode zu warten, bis alle Tasks oder auch nur irgendeiner fertig sind. Dazu bietet TTask die Methoden WaitForAll und WaitForAny. Beide erwarten ein Array of ITask als Parameter.

var myTasks: array of ITask;
begin
  SetLength(myTasks, 2);

  // Task 1
  myTasks[0] := TTask.Create(procedure ()
    begin
      sleep(3000); // 3 seconds
    end);
  myTasks[0].Start;

  // Task 2
  myTasks[1] := TTask.Create(procedure ()
    begin
      sleep(5000); // 5 seconds
    end);
  myTasks[1].Start;

  TTask.WaitForAll(myTasks);
  ShowMessage('Alle fertig!');
End;

Wer diese Anwendung aus der Delphi-IDE startet, sieht im Ereignisprotokoll den Start der beiden Tasks („Thread-Start“).

TInterlocked

Kleiner Abstecher, der allerdings auch mit Nebenläufigkeit zu tun hat: Möchte man aus mehreren Threads auf dieselbe Variable zugreifen, z.B. um einen Wert hochzuzählen, kann das zu Problemen führen. Um den Zugriff auf Variablen threadsafe zu machen, gibt es die Klasse System.SyncObjs.TInterlocked.

Diese Klasse bietet eine Reihe statischer Methoden, z.B. Add und Increment, die den Wert einer Variablen erhöhen:

var value: Integer;
begin
  TInterlocked.Add(value, 1);
  // gleichbedeutend mit:
  TInterlocked.Increment(value);

Download Beispiel-Anwendung (Parallele Tasks, ZIP, 57 KB)

Ein Gedanke zu „Parallelisierung mit Delphis Parallel Library“

  1. In der Routine

      ...
      TParallel.For(1, 100000, procedure(I: Integer)
      Begin
        If IsPrime(i) Then
          inc(Total);
      End);
      ...

    würde ich statt inc(Total) die Anweisung TInterlocked.Increment(Total) verwenden, sonst stimmt die Anzahl der ermittelten Primzahlen nicht.

Kommentare sind geschlossen.