| 
| Autor | Beitrag |  
| delfiphan 
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: Fr 04.09.09 19:27 
 
(Aus diesem Post  entstanden)
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-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 
 | procedure TForm1.Button1Click(Sender: TObject);begin
 
 if TEventFiber.RerunInFiber(Self, Button1Click) then
 Exit;
 
 try
 TFiber.Current.SwitchToWorkerThread;
 
 
 finally
 TFiber.Current.SwitchToMainThread;
 end;
 
 
 end;
 |  // Edit: Race condition fixed
Einloggen, um Attachments anzusehen!
 
 Zuletzt bearbeitet von delfiphan am Fr 29.07.11 12:52, insgesamt 11-mal bearbeitet
 Für diesen Beitrag haben gedankt: bummi, Hidden
 |  |  |  
| delfiphan  
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: Fr 02.04.10 15:42 
 
Die Library scheint niemand zu mögen    habe sie jetzt noch weiter vereinfacht. 
 Bei Events vom Typ TNotifyEvent  muss man jetzt nur noch TEventFiber.RerunInFiber  ausführen, um die Vorteile von Fibers nutzen zu können. Beispiel:
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 
 | procedure TForm1.Button1Click(Sender: TObject);begin
 
 if TEventFiber.RerunInFiber(Self, Button1Click) then
 Exit;
 
 try
 TFiber.Current.SwitchToWorkerThread;
 
 
 finally
 TFiber.Current.SwitchToMainThread;
 end;
 
 end;
 |  |  |  |  
| alzaimar 
          Beiträge: 2889
 Erhaltene Danke: 13
 
 W2000, XP
 D6E, BDS2006A, DevExpress
 
 | 
Verfasst: Fr 02.04.10 16:41 
 
Das ist zu hoch für 99.9% aller Programmierer. _________________ Na denn, dann. Bis dann, denn.
 |  |  |  
| Martok 
          Beiträge: 3661
 Erhaltene Danke: 604
 
 Win 8.1, Win 10 x64
 Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
 
 | 
Verfasst: Fr 02.04.10 16:58 
 
Nicht unbedingt zu hoch, aber sowas ohne echte Sprachfeatures zu machen, ist irgendwie... unschön.
 Vielleicht könnte man da mit den DLangExtensions was machen?
 _________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
 |  |  |  
| Webo 
          Beiträge: 577
 Erhaltene Danke: 14
 
 Win 7, Debian
 C# (Visual Studio 2013), PHP, C, C++ (Eclipse, KDevelop)
 
 | 
Verfasst: Fr 02.04.10 18:01 
 
Jetzt, wie ich mir den Eingangstext so durchgelesen habe scheint das ein sehr interessantes Thema zu sein. Auch wenn ich direkt nicht weiß, wo ich sowas einbauen könnte, ich werde gleich mal damit rumspielen. Mal schauen was sich so ergibt   _________________ Man kann nur das aus dem Ärmel schütteln, was man auch vorher reingesteckt hat.
 |  |  |  
| delfiphan  
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: Fr 02.04.10 18:03 
 
Ich habe diese Library verwendet, um bestehenden Code multi-threaded zu machen. Z.B. wechsle ich bei langen DB-Queries schnell in einen WorkerThread (Achtung, die DB-Library muss natürlich Thread-Safe sein!). Wenn die Query fertig ist, geht es wieder weiter mit dem bestehenden Kontrollfluss im MainThread. Interessant auch bei blockierenden Calls bei Indy-Komponenten. 
 Kompliziert ist das ganze nicht, zu mindest nicht in der Anwendung. Im Gegenteil, es soll Threading vereinfachen. 
 Wenn man mit TThread was machen will, muss man ja:
 - Von TThread ableiten. Der Code, der im Thread läuft in eine Execute-Methode packen. 
 - Informationen, die der Thread braucht muss man separat übergeben z.B. über public Properties in der abgeleiteten Klasse. 
 - Um die Kontrolle zurück an den MainThread zu geben muss man Synchronize verwenden. Die nimmt wieder nur Methoden ohne Argumente entgegen. Man muss wieder mit irgend welchen privaten Variablen arbeiten, die vielleicht nur temporärer Natur sind. 
 - Bei Exceptions im Thread muss man die selbst wieder an den MainThread kommunizieren. 
 	  |  Martok hat folgendes geschrieben  : |  	  | sowas ohne echte Sprachfeatures zu machen, ist irgendwie... unschön. | 
 Da gebe ich dir Recht. Ich würde so eine Funktionalität auch nicht in die RTL/VCL aufnehmen, wenn ich bei Borland arbeiten würde. Aber praktisch finde ich die Library trotzdem. |  |  |  
| Webo 
          Beiträge: 577
 Erhaltene Danke: 14
 
 Win 7, Debian
 C# (Visual Studio 2013), PHP, C, C++ (Eclipse, KDevelop)
 
 | 
Verfasst: Fr 02.04.10 18:31 
 
_________________ Man kann nur das aus dem Ärmel schütteln, was man auch vorher reingesteckt hat.
 |  |  |  
| Luckie Ehemaliges Mitglied
 Erhaltene Danke: 1
 
 
 
 
 | 
Verfasst: Fr 02.04.10 18:51 
 |  |  |  
| Webo 
          Beiträge: 577
 Erhaltene Danke: 14
 
 Win 7, Debian
 C# (Visual Studio 2013), PHP, C, C++ (Eclipse, KDevelop)
 
 | 
Verfasst: Fr 02.04.10 19:27 
 
	  |  Luckie hat folgendes geschrieben  : |  	  | Vorsicht! Fibers sind keine Threads! | 
 Geht klar Meister     (  ) ... dann ist es eben "ein Kinderspiel, Sachen in Pseudo-Threads auszulagern". Nee, Spaß beiseite, danke der Richtigstellung, man will ja dazu lernen.
 Ob Pseudo-Thread oder nicht, aufjedenfall eine sehr nette Sache._________________ Man kann nur das aus dem Ärmel schütteln, was man auch vorher reingesteckt hat.
 
 Zuletzt bearbeitet von Webo am Sa 03.04.10 09:07, insgesamt 1-mal bearbeitet
 |  |  |  
| delfiphan  
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: Fr 02.04.10 19:49 
 
Fibers sind keine Threads, das wurde hier nirgends behauptet. Wenn ich oben von Threads oder Threading spreche, meine ich auch Threads.
 In dieser Library geht es darum, mittels Fibers Threading zu vereinfachen. Die Vereinfachung resultiert daraus, dass man jeweils selbst wählen kann, in welchem Thread ein bestimmter Fiber läuft und den Thread auch jederzeit wechseln kann.
 
 Diese Library enthält TFiber, eine Klasse, die Fibers implementiert. Diese, zusammen mit anderen Klassen in der Library, vereinfachen Threading.
 |  |  |  
| Luckie Ehemaliges Mitglied
 Erhaltene Danke: 1
 
 
 
 
 | 
Verfasst: Fr 02.04.10 20:27 
 
	  |  delfiphan hat folgendes geschrieben  : |  	  | Fibers sind keine Threads, das wurde hier nirgends behauptet. | 
 Dich meinte ich ja auch gar nicht, sondern Webo. |  |  |  
| delfiphan  
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: Sa 30.10.10 08:43 
 
Hab die API noch ein wenig angepasst für Leute mit einer neueren Version von Delphi. Man kann einen Fiber nun als anonyme Methode von irgendwo aus starten. 
 Beispiel:
 		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 
 | procedure TForm1.Button1Click(Sender: TObject);begin
 
 TFiber.Run(
 procedure
 var
 I: Integer;
 begin
 (Sender as TButton).Caption := 'Calculating...';
 
 TFiber.Current.SwitchToWorkerThread;
 try
 for I := 0 to 99 do
 Sleep(100);
 finally
 TFiber.Current.SwitchToMainThread;
 end;
 
 (Sender as TButton).Caption := 'Calculation completed';
 end
 );
 
 end;
 |  
 Zuletzt bearbeitet von delfiphan am So 31.10.10 14:42, insgesamt 1-mal bearbeitet
 |  |  |  
| BenBE 
          Beiträge: 8721
 Erhaltene Danke: 191
 
 Win95, Win98SE, Win2K, WinXP
 D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
 
 | 
Verfasst: Sa 30.10.10 23:47 
 
Sollte das Switchen zwischen MainFiber und TaskFiber nicht von der Fiber-Klasse realisiert werden? Also zumindest für die Initialisierung und Finalisierung des Fibers? _________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
 |  |  |  
| bummi 
          Beiträge: 1248
 Erhaltene Danke: 187
 
 XP - Server 2008R2
 D2 - Delphi XE
 
 | 
Verfasst: So 31.10.10 10:11 
 
Interessante Klasse, ich werde mal Versuchen das ganze zu verstehen. |  |  |  
| delfiphan  
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: So 31.10.10 12:43 
 
	  |  BenBE hat folgendes geschrieben  : |  	  | Sollte das Switchen zwischen MainFiber und TaskFiber nicht von der Fiber-Klasse realisiert werden? Also zumindest für die Initialisierung und Finalisierung des Fibers? | 
 Ich versteh nicht ganz; es gibt (im Beispiel oben) nur einen Fiber. Der Fiber wird dann auf dem einen oder anderen Thread ausgeführt. 
 Ich hab jetzt die API für die 2010er Version vereinfacht, sodass es nur noch 1 Klasse gibt (TFiber). 
 Zum Ausführen in einem Fiber:
 TFiber.Run(<anonyme Methode>) Innerhalb eines Fibers kann über TFiber.Current  auf die aktuelle Instanz zugegriffen werden. |  |  |  
| BenBE 
          Beiträge: 8721
 Erhaltene Danke: 191
 
 Win95, Win98SE, Win2K, WinXP
 D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
 
 | 
Verfasst: So 31.10.10 16:52 
 
Mich hatten die SwitchToMainThread und SwitchToWorkerThread-Aufrufe etwas irritiert. Daher die Frage. _________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
 |  |  |  
| delfiphan  
          Beiträge: 2684
 Erhaltene Danke: 32
 
 
 
 
 | 
Verfasst: So 31.10.10 17:10 
 
SwitchToMainThread und SwitchToWorkerThread wird ja von der Fiber-Klasse realisiert. Die Methoden werden von der aktuellen Fiber-Instanz ausgeführt. Die aktuelle Instanz wird über TFiber.Current abgerufen. (Die ehem. TAnonymousFiber-Klasse leitete von TFiber ab, daher hat TFiber.Current die TAnonymousFiber-Instanz zurückgegeben. Die Klasse gibt's jetzt aber nicht mehr). 
 Sieht vielleicht auf den ersten Blick ungewöhnlich aus, aber schlussendlich spart es Tipparbeit. Mit der Klasse kann ich "freihändig" Fibers und Threads nutzen, d. h. ich muss weder eine Variable deklarieren noch eine Klasse implementieren. Um das Beispiel oben mit TThread zu realisieren, müsste man zuerst eine Klasse schreiben (von TThread ableiten), den Button als Feld zuweisen, die Methode Execute overriden und darin am Schluss wieder Synchronize aufrufen, um den Button-Text wieder anzupassen. Das ganze Exception-Handling im Thread kommt noch hinzu. Viel zu viel Aufwand für Implemenation, Testen und Wartung; ausserdem ist der Code nicht wirklich lesbarer. (bei dieser Argumentation müsste man sich aber fragen, ob Delphi die richtige Sprache dafür ist).
 |  |  |  
| Fiji Hält's aus hier
 Beiträge: 1
 
 
 
 
 | 
Verfasst: So 27.07.14 13:32 
 
It seems it will not work with 64 bit. |  |  |  |