Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi TThread.Syncronize und critical section (https://www.delphipraxis.net/87111-tthread-syncronize-und-critical-section.html)

Arnulf 23. Feb 2007 12:51


TThread.Syncronize und critical section
 
Ich hab mir jetzt mal das tthread objekt angeschaut und finde das eigentlich recht komfortabel.
Nur hab ich ein paar fragen zu methoden:

1. Sobald ich syncronize (fillListenFeld) aufrufe wird der zugriff des mainthreads gesperrt ( syncronisiert )
und ich kann auf den listenobjekten oder labels des mainthreads herumfurwerken.
es ist dabei nicht mehr notwendig criticalsection zu benutzen?????

2. wenn ich eine aus der syncronized procedure eine andere Funktion aufrufe wird diese
ebenfalls syncronisiert aufgerufen?????

Im prinzip möchte ich nur ein ListView und zwei lablels aktuallisieren.
keine zeitraubende sache - aber es muss hald syncronisiert werden.

3. critical section muss ich in syncronized methoden nicht aufrufen nehme ich an ???
critical section dient nur zu dirrekten mannipulation von variablen oder eben kurz mal was auslesen ??

Ich wollte theoretisch fragen wie die methoden funktionieren bzw. ob ich das richtig sehe.

lg
Arnulf

shmia 23. Feb 2007 13:32

Re: TThread.Syncronize und critical section
 
Zitat:

Zitat von Arnulf
1. Sobald ich syncronize (fillListenFeld) aufrufe wird der zugriff des mainthreads gesperrt ( syncronisiert )
und ich kann auf den listenobjekten oder labels des mainthreads herumfurwerken.
es ist dabei nicht mehr notwendig criticalsection zu benutzen?????

Criticalsections werden hier nicht benötigt.
Zitat:

Zitat von Arnulf
2. wenn ich eine aus der syncronized procedure eine andere Funktion aufrufe wird diese
ebenfalls syncronisiert aufgerufen?????

Ja.
Zitat:

Zitat von Arnulf
3. critical section muss ich in syncronized methoden nicht aufrufen nehme ich an ???
critical section dient nur zu dirrekten mannipulation von variablen oder eben kurz mal was auslesen ??

[TThread].Synchronize funktioniert so:
der Thread schickt dem Hauptthread eine Windows-Botschaft (Message).
In der Botschaft ist ein Methodenzeiger (also Adresse des Threadobjekts + Adresse der Procedure) enthalten.
Der Hauptthread arbeitet ständig seine Messagequeue ab, bis er auf diese Botschaft tritt.
Die Procedure, die Synchronize übergeben wurde wird nun im Kontext des Hauptthreads ausgeführt;
das ist der ganze Trick.

SirThornberry 23. Feb 2007 13:39

Re: TThread.Syncronize und critical section
 
durch den Aufruf von Syncronize wird die Methode welche mit Syncronize aufgerufen wird im Context des Hauptthread ausgeführt (so würde sie ohne Thread laufen) und der Thread läuft erst weiter wenn der Aufruf von Syncronize zurück gekehrt ist. Wenn du also innerhalb der Syncronisierten Methode eine andere aufrufst läuft diese logicher Weise auch im Context des Hauptthreads.

CrititcalSections hingegen laufen weiterhin in dem Thread wo man sie betritt und CriticalSections sichern ab das nicht mehrere Threads gleichzeitig diese Section betreten.

Arnulf 23. Feb 2007 14:06

Re: TThread.Syncronize und critical section
 
danke das macht alles klipp und klar :)
lg
Arnulf
edit:
zumindestens werde ich das so verwenden:
wenn listenfelder auffülle oder oder ähnliches also viele operationen ausführe, dann verwende ich syncronize
wenn ich nur schnell ein label ändern will auf der hauptform dann nehm ich critcal section.

critical section also bei allen dingen die keine weiteren aktionen auslösen ( wie onchange oder sowas ).
sondern einfach nur werte ändern.

und natürlich dem context des programms entsprechen :)

lg
Arnulf

SirThornberry 23. Feb 2007 14:38

Re: TThread.Syncronize und critical section
 
stop, wenn du vcl-dinge änderst musst du immer syncronize verwenden. Wenn du also auf eine Canvas des Hauptthreads malst musst du in diesem Threadcontext sein was nur mit syncronize geht. Wenn du eine einfache TList hast ist das egal. Aber sobald irgendwas grafiches gemacht wird immer syncronize verwenden (oder die daten in eine Variable schreiben und der Hauptthread liest diese Variable immer wieder aus und aktuallisiert (polling))

Arnulf 23. Feb 2007 21:17

Re: TThread.Syncronize und critical section
 
ach verstehe - und ich spiel jetzt schon eine stunde herum und verstehe einfach nicht warum
critical section bei einer tlistbox ständig hängt und mein programm nicht mehr reagiert.

hm dann muss ich mir wieder alles anders überlegen.
eigentlicht wollte ich eine auftragsliste für meinen thread haben.

der holt sich immer wenn er gerade was abgearbeitet hat aus einer list den nächsten auftrag - bzw. wartet er auf die nächste eingabe ( aus der liste ).

das ist so natürlich hinfällig
da muss ich mir jetzt etwas ganz anderes übleregen - weil bei so einer auftragsliste
jedesmal syncronize aufzurufen ist vielliecht auch nicht das ware.

hmmm... was mach ich denn jetzt ....

naja
danke auf jeden fall - dann probier ich nicht länger das zum laufen zu bekommen :)
vermutlich ist es das besste die auftragsliste nicht grafisch zu implementieren - und einfach ein gutes altes array zu nehmen :)

lg
Arnulf

C.Schoch 24. Feb 2007 00:02

Re: TThread.Syncronize und critical section
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
Willst du Threads mit Aufträgen versorgen?
Dazu hab ich hier ein Beispiel ist aber nicht von mir.

Arnulf 25. Feb 2007 21:43

Re: TThread.Syncronize und critical section
 
Hab mir das beispiel kurz angeschaut.
irgendwie war mir das zu kompliziert :) - nein ich mach so meine ersten versuche mit der thread klasse und irgendwie funktioniert eh alles ganz gut - ohne stress.
ich hab die jobliste anders gemacht - hab da auch spezielle anforderungen.

zum beispiel verwende ich einfach syncronize dafür und mach mir damit garkeinen stress.
Beispiel:
ich hab einen indy udp client am laufen.
eine string var - in die ich immer den send string schreibe.
vom thread also:
Delphi-Quellcode:
      synchronize ( fMain.GetNextMessage );
hier die procedure.

Delphi-Quellcode:
procedure TfMain.GetNextMessage;
begin
if (fMain.gsMessage.Items.Count > 0) then
begin
     UdpThread.udpNextmsg := fMain.gsMessage.Items.Strings[0];
     fMain.gsMessage.Items.Delete(0);
end
end;
udpNextmsg ist jetzt eine variable des threads deshalb hab ich die dann im thread zur verfügung

wenn ich etwas in die liste einfügen will ( in meinem fall hab ich die an erste stelle geschoben ):
Delphi-Quellcode:
procedure AddFirstgsMessage (s : string );
begin
   fMain.gsMessage.Items.Insert(0,s);
end;
Bei mir funktioniert das sehr gut - wenn das absoluter blödsinn ist, dann mir bitte bitte mitteilen :)

inzwischen hab ich auch eine Frage.
der thread läuft in einer while schleife

Delphi-Quellcode:
while not (terminated) do
begin
bla bla
sleep(1);
end;
//// hier kommt jetzt der code den ich nach thread.terminate ausführen wollen würde.
der Thread wird schön beendet, aber der code nach der while schleife leider nie ausgeführt.
warum??
und welche destructor methode könnte ich verwenden?
lg
Arnulf

C.Schoch 25. Feb 2007 23:58

Re: TThread.Syncronize und critical section
 
Hi,
Das der Code nach der Schleife nicht ausgeführt wird kann eigentlich nicht sein, auser es gibt eine Exception.
Hast du das ganze mal per Einzelschritt (F7) im Debugger verfolgt?

Arnulf 26. Feb 2007 16:40

Re: TThread.Syncronize und critical section
 
es funktioniert jetzt
frag mich nicht warum :)
danke jedenfalls

lg
Arnulf


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:31 Uhr.

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