TFiber
Die Klasse TFiber stellt eine separate "Ausführungsumgebung" zur Verfügung, die unabhängig von Threads existiert. Diese hat einen eigenen Satz von Registers, Stack,
Exception Chain und Instruction Pointer.
Im Gegensatz zu einem Thread wird ein Fiber nicht vom Betriebsystem verwaltet und ausgeführt, sondern muss manuell in einem Thread der Wahl ausgeführt werden. Daher sieht das Starten eines Fibers erst mal aus wie ein normaler Funktionsaufruf. Der Vorteil ist aber, dass die Ausführung eines Fibers an einer beliebigen Stelle gestoppt und zu einem späteren Zeit forgesetzt werden kann. Ausserdem ist es möglich, mit einem einfachen Funktionsaufruf an beliebiger Stelle im Kontrollfluss ein Fiber von einem Thread auf einen anderen zu transferieren.
Anwendungsfälle
- Fibers können verwendet werden, um an beliebiger Stelle während der Ausführung den Thread zu wechseln, bspw. um den MainThread freizugeben.
- Fibers können verwendet werden, um CoRoutinen zu implementieren.
- Fibers können die Anzahl Threads reduzieren, wenn sehr viele Ausführungspfade existieren, diese aber nicht ständig laufen. So kann der Fiber inaktiv sein, bis wieder Arbeit ansteht, um dann wieder in einem Thread aus einem Threadpool ausgeführt zu werden.
Features
- Transparentes
Exception Handling über Thread-Grenzen hinweg.
- "Inline" Wechsel zwischen MainThread und Worker-Thread aus einem ThreadPool
- Direkter Transfer von einem Fiber in einen anderen möglich
Methoden von TFiber
-
SwitchToWorkerThread: Ausführung in einem WorkerThread fortführen
-
SwitchToMainThread: Ausführung im MainThread fortführen
-
Yield: Kontrolle an Thread zurückgeben
-
Transition: Kontrolle an anderen Fiber übergeben
-
Resume: Kontrolle von Thread an Fiber übergeben
Properties von TFiber
-
FreeOnTerminate: Instanz automatisch freigeben, wenn der Ausführungspfad des Fibers abgeschlossen ist.
Die Units mit Beispielprojekt im Anhang oder
hier. Falls jemand nach einer ThreadPool Implementierung sucht ist hier eine mit dabei.
Beispiel
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
Fiber: TEventFiber;
begin
Fiber := TEventFiber.Create;
Fiber.FreeOnTerminate := True;
Fiber.Run(Sender, Button1Click2);
end;
// This code is run in a fiber
procedure TForm1.Button1Click2(Sender: TObject; Fiber: TFiber);
begin
// ...
// Switch to worker thread, free UI thread
Fiber.SwitchToWorkerThread;
try
// Do something in the worker thread
// ...
finally
// Switch back to MainThread
Fiber.SwitchToMainThread;
end;
// ...
end;
Edit: Falsches Zip-File durch korrektes ersetzt