Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi TThread: MainThreadsynchronisation ohne Synchronize (https://www.delphipraxis.net/120041-tthread-mainthreadsynchronisation-ohne-synchronize.html)

sirius 4. Sep 2008 20:36


TThread: MainThreadsynchronisation ohne Synchronize
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich weiß der Andreas hat da auch was. Aber ich will auch mal!

Ich habe eine weitere Möglichkeit zusammengebaut um einen Thread (A) mit einem Thread (B) zu snychronisieren. Dies geht aber nur ausschließlich dann, wenn der Thread A von Thread B aus gestartet wurde. Weitere "Quersynchronisationen" sind nicht möglich. Gedacht ist es um einfach einen speziellen Thread mit dem Mainthread zu synchronisieren. Dabei wurde dieser spezielle Thread auch vom MainThread gestartet. (Ich hoffe soweit ist alles klar)

In der Unit im Anhang liegt die Klasse TThreadEx, welche von TThread abgeleitet ist. Die Anwendung erfolgt über die beiden Methoden StopMainThread und ContinueMainThread:
Delphi-Quellcode:
//alles wie gehabt bei TThread:
type TmyThread=class(TThreadEx)
       protected
         procedure Execute; override;
       ...
     end;
 
...

procedure TmyThread.execute;
begin
...
   
    stopmainthread; //Hier wird der MainThread angehalten und man kann auf Variablen etc. des Mainthreads zugreifen
    try
      form1.memo1.lines.add('Hallo MainThread');
    finally
      continuemainthread; //und jetzt darf der MainThread auch wieder weitermachen
    end;
...

end;
Was sind die Vorteile gegenüber synchronize:
  1. man braucht nicht diesen umständlichen Aufruf von Synchronize, bei dem keine Variablenübergabe möglich ist
  2. diese Variante funktioniert auch in einer DLL (synchronize nicht)

Es war einfach eine Idee von mir, die ich mal ausprobieren musste. Bei meinen Versuchen klappt es ohne Probleme.


Edit 1+2: neue Version, jetzt würde der Mainthread auch bei einem plötzlichen Ende (Exception, Error) des SubThreads weiterlaufen

Apollonius 4. Sep 2008 20:46

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Sieht vernünftig aus. Zwei Sachen sollte man allerdings noch erwähnen:
1. Es werden Fenster erzeugt (was per se natürlich kein Nachteil ist, man sollte es nur erwähnen - wenn man den Desktop wechseln will, ist das z.B. denkbar ungünstig) - daher wird im Elternthread auch eine Nachrichtenschleife gebraucht.
2. Im Gegensatz zu Synchronize wird nicht in den Elternthread gewechselt, es wird lediglich der Elternthread gestoppt. Wenn man daher z.B. Fenster erzeugt, gehören sie dem Kindthread.

Luckie 4. Sep 2008 20:55

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Das ist aber nicht ungefährlich, was du da machst. Thread A startet Thread B. Thread B hlät Thread A in einer CriticalSection an, denn Thread B weiß ja nicht, was Thread A gerade macht. Wenn jetzt andere darauf warten das Thread A die CritialSection verlässt, kann das zu Performanceeinbußen führen. Aber richtig schlimm wird es, wenn Thread B abstürzt und Thread A nicht mehr startet. Dann hängen alle Threads, die auf das Freigeben der CriticalSection warten.

Deswegen sollte man es vermeiden einen Thread von aussen anzuhalten. Ein Thread sollte nur sich selber anhalten oder beenden. Meist löst man dass so, dass man ein Flag setzt, welches vom Thread regelmäßig abgefragt wird.

Apollonius 4. Sep 2008 20:59

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Da hat Sirius schon mitgedacht. Es funktioniert ja gerade nicht über ein einfaches SuspendThread, sondern es wird eine Nachricht verschickt. Der Thread kann somit nur in Aufrufen von GetMessage oder PeekMessage angehalten werden.

sirius 5. Sep 2008 08:02

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Danke für die Kommentare.

Apollonius:
zu 1: Jep, aber die VCL erzeugt auch ständig neue Fenster (z.B. TTimer), auf diesem Marktplatz bin ich nicht neu. Das Problem mit den Desktops habe ich nicht verstanden. Habe auch noch nie mit mehreren Desktops gearbeitet. Gibt es dar Probleme, und welche?
zu 2: Das sollte man aber auch erwarten wenn man den Code (der Fenstererzeugung) innerhalb der Execute-Methode schreibt. Aber ich sehe ein, dass jemand vielleicht eine Instanz einer neuen VCL-Komponente erstellen will. Das geht so nicht. Bei Threadsynchronisation muss man eben immer aufpassen. Das kann ich durch das klein bisschen Code nicht abnehmen.
btw: Kindthread ist eine schöne Bezeichnung. Ich habe bereits nach so etwas gesucht.

Luckie:
Ich arbeite doch gar nicht mit Critical Sections. Ok, ich nehme Events und das hat alles miteinander zu tun.
Die Idee ist, dass bei StopMainThread der MainThread durch ein Ereignis in eine Methode "gelockt" wird, in der eine Art "Schleife" ohne Application.ProcessMessages ist. Diese "Schleife" (nicht ganz Schleife ist ja nur eine Wait-Function der WinAPI) wird durch das warten auf ein Event (welches durch StopMAinThread gesetzt wird) realisiert.
Nebenbei ist da tatsächlich noch eine Schleife drumrum wegen den synchronen Messages (ob das wirklich notwenig ist, weiß ich nicht).
Die Sache mit dem Thread von außen anhalten, musst du noch mal spezifizieren. Das habe ich nicht verstanden.

Luckie 5. Sep 2008 08:59

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Was ist dir genau unklar in meinem Posting?

sirius 5. Sep 2008 09:16

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Der Zusammenhang von deinem Post mit meinem Code leuchtet mir auf Anhieb nicht ein. Aber ich arbeite an mir ;)

Ich sehe grad noch eine Verbesserung darin, dass ich bei msgWaitForMultipleObjects auch noch den Thread (B) mit angeben sollte, falls dieser abstürzt. Aber man sollte natürlich immer ein try-finally um das Anhalten des Threads basteln. Falls du das meinst, Luckie.

Luckie 5. Sep 2008 09:25

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Nun, dein Beispielcode im ersten Posting vermittelte für mich den Eindruck, als wenn du einen Thread von aussen anhalten würdest. Daraufhin hab eich versucht darzustellen, warum man dies nicht tun sollte und wie man es statt dessen besser macht.

sirius 5. Sep 2008 17:00

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Naja, den Mainthread anhalten geht ja nicht (oder). Den kann man nur pausieren (wait for some objects) lassen.

Apollonius 5. Sep 2008 17:45

Re: TThread: MainThreadsynchronisation ohne Synchronize
 
Bezüglich Desktops: Wenn du mit SetThreadDesktop den Desktop eines Threads ändern will (z.B. um auf im Fenster anzuzeigen) darf dieser auf dem alten Desktop keine Fenster haben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:23 Uhr.
Seite 1 von 2  1 2      

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