Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Trotz Threads keine Reaktion (https://www.delphipraxis.net/107165-trotz-threads-keine-reaktion.html)

Green 24. Jan 2008 17:11

Re: Trotz Threads keine Reaktion
 
Zitat:

Zitat von sirius
@Lossey:
Deine Einwände sind vollends richtig. Aber ich vermute, dass da in mehreren Kapiteln/Abschnitten noch ein bisschen mehr aufgebaut wird. Vielleicht wird ja daraus noch eine Datenbankanwendung oder eine Anwednung mit verteilten Processen.

Nein, ist nur ein kleines Beispiel...

Hab mir schon was neues ausgedacht (n Timer marke Eigenbau).
Aber das mit dem Synchronisieren, das hab ich noch nicht geblickt! was genau macht das denn jetzt??

sirius 24. Jan 2008 18:18

Re: Trotz Threads keine Reaktion
 
Synchronisieren
Problem: Da du nie weist wo welcher Thread gerade ist im Programmablauf, kann es passieren, dass mehrere Threads gleichzeit auf denselben Speicherplatz zugreifen. Ungünstigerweise schreibt der eine gerade was, während der andere genau an der Stelle liest. Dadurch entstehen nicht nur Fehler weil die Werte falsch sind, Es kann auch ganz leicht zu Speicherzugriffsverletzungen führen. Wenn zum Beispiel der eine Thread dachte die dynamische Variable existiert noch, während der andere sie grad löscht (und neu anlegt mit anderer Größe).

Lösung:
Nun kann man solche Zugriffe absichern (z.B.) über Critical Sections. Da das aber recht kompliziert ist und wir mit Delphi ja einfach klicken und programmieren wollen, hat man sich synchronize ausgedacht.

Wat macht dat nun:
Das ist ein bisschen tricky. Prinzipiell gibt es eine globale Liste für Methoden, an die jeder Thread etwas anhängen kann. An diese Liste hängt synchronize einfach deine Methode ran. Und jetzt wartet dein Thread (bleibt einfach stehen) erstmal.
Jetzt ist der MainThread drann. Wenn der grade nix besseres zu tun hat, dann schaut er mal, ob in der Liste etwas zum abarbeiten drin steht. Wenn das der Fall ist führt er die Methode aus und löscht sie aus der Liste. Dadurch führst du die Methode, die du synchronize übergeben hast im MainThread durch während dein Thread schläft. Dein Thread wartet nämlich auf ein Signal vom MainThread, dass der Mainthread mit der Methode fertig ist. Das ist alles. Und du hast den Vorteil: du kannst problemlos auf Variablen aus MainThread und aus deinem Thread zugreifen.
Synchronize hat aber auch Nachteile. Einen dürftest du aufgedeckt haben. Die Liste fragt der Mainthread in einer while-Schleife ab: "while List.count>0 do". Das Problem dabei entsteht, wenn es mehrere Threads gibt, die ununterbrochen die Liste füllen. Dadurch kommt der Mainthread aus dieser Schleife nicht mehr raus. Der eine Thread wartet zwar bis seine Methode abgearbeitet ist aber unterdessen füllen die anderen beiden Threads die Liste wieder auf. Dadurch macht der Mainthread nix anderes mehr, als die Liste abzuarbeiten und reagiert auf keine Messages mehr. Kommt also gar nicht zum Zeichnen und interessiert sich auch nicht für sonstige Eingaben.

Es gibt mit synchronize noch andere Probleme, die fallen mir nur grad nicht ein. Die letzten Sätze sollen diese Methode nicht durch den Dreck ziehen, ich wollte nur kurz aufzeigen, dass es zwar schön einfach ist. Aber man sollte den Mechanismus immer bedenken.

Green 24. Jan 2008 21:54

Re: Trotz Threads keine Reaktion
 
Ok, kann man das mit einem Stack vergleichen?

Dann frage ich mich nur warum ich in diesem Fall mit Exceptions zugeballert werde wenn ich Synchronize weglasse? Die Threads greifen doch auf verschiedene Objekte zu?!?

sirius 24. Jan 2008 22:05

Re: Trotz Threads keine Reaktion
 
Ein Stack...ja. Eben eine Liste im FIFO-Prinzip. Und jedesmal wenn ein Thread synchronize aufruft, setzt er der Liste eine Methode hinten an (und zwar die Methode die man übergibt; hier: DoPaint) und dann wartet der Thread bis die Methode vom Mainthread ausgeführt wurde.

Du benutzt zwar verschiedene Paintboxen. Aber die VCL hat dahingehend irgendwo einen Haken. Hier dürfte der Pen- oder der BrushManager der Auslöser sein. Diese sind global und darauf greift jedes Grafikobjekt zu.

mkinzler 24. Jan 2008 22:09

Re: Trotz Threads keine Reaktion
 
Zitat:

Ein Stack...ja. Eben eine Liste im FIFO-Prinzip.
Eher LIFO

sirius 24. Jan 2008 22:15

Re: Trotz Threads keine Reaktion
 
Zitat:

Zitat von mkinzler
Zitat:

Ein Stack...ja. Eben eine Liste im FIFO-Prinzip.
Eher LIFO

Ein Stack ja, aber die SyncListe nicht ;) Deswegen mein zögerndes "Ja"

Edit: Oder muss man da generell Nein sagen, da Stack immer LIFO ist?

Lossy eX 26. Jan 2008 08:47

Re: Trotz Threads keine Reaktion
 
Ein Stack ist Last In First Out. Also es wird etwas oben drauf gepackt und das muss auch als Erstes wieder entfernt werden. (Bücherstapel)

Das Synchronize arbeitet aber mit einer Liste bei der das erste Element entfernt wird und alle anderen durch Add hinzugefügt werden. Also First In First Out. Und das ist eine klassische Liste oder auch Queue. (Warteschlange)

@Green: Knallen tut es unter anderem auch deswegen, weil die Paintboxen zwar unterschiedliche Objekte sind aber diese liegen alle auf dem gleichen Fenster. Und Paintboxen sind im Vergleich zu einem Panel kein echtes Windowsfenster. Sondern "lediglich" eine Kappselung eines Canvas. Damit zeichnen alle Threads auf das gleiche Windowsfenster. Erschwerend kommt hinzu, dass die GDI nur Anwendungsübergreifend sicher ist. Aber innerhalb einer Anwendung nicht Threadsafe ist.

Es muss nicht immer knallen. Ich hatte schon mal das Phänomen, dass er einfach aufgehört hat zu zeichnen. Vollkommen willkührlich. Das macht das Problem auch so unberechenbar und gefährlich.

negaH 26. Jan 2008 09:32

Re: Trotz Threads keine Reaktion
 
Das GDI = Graphics Device Interface ist eine Schnittstelle des Windows-OS das es ermöglicht Bilder in die Grafikkarte zu zeichnen. Wenn nun das GDI nicht threadsafe ist so ist es auch nicht das Windows-Fensterhandling das das GDI benutzzt um den Inhalt der Fenster zu zeichnen und somit ist es auch nicht die VCL threadsafe die auf beide APIs aufsetzt. Ergo: Zeichen/Fensterroutinen niemals in Threads benutzen, und somit ist dein Beispiel von Grund auf fürn Popo. Man kann also diesen "fehler" nicht der VCL in die Schuhe schieben, obwohl sie ihren Teil noch zusätzlich zur Thread-Unsicherheit beiträgt.

Gruß Hagen

rawsoul 31. Jan 2008 23:12

Re: Trotz Threads keine Reaktion
 
Ich denke, Synchronize würde mir bei meinem aktuellen Problem auch helfen. Allerdings ist Synchronize bei mir als Konstante (Integer) definiert, nicht als Methode. Was ist denn hier schiefgelaufen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:38 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz