| Autor |
Beitrag |
Hendi48
      
Beiträge: 271
|
Verfasst: Mo 24.09.07 11:35
Hi,
ich habe einen Thread der mehrfach gestartet wird. Das geht auch ohne Probleme, nur möchte ich nun wissen ob alle Threads fertig sind. Dazu habe ich eine Array of Boolean deklariert und die Threads haben immer eine Zahl und die setzen dann Array[threadzahl] auf True. Ich weiß aber nicht, wie ich prüfen kann ob jetzt alle Werte in der Array auf True sind. Ich habe mal das ausprobiert:
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: 25:
| var BoolCheck0r: Boolean;
procedure CheckThreads; var i: Integer; begin BoolCheck0r := True; for i := 0 to high(sizethreaddone) do if not sizethreaddone[i] then begin BoolCheck0r := false; break; end; end; begin
repeat CheckThreads; until BoolCheck0r;
showmessage('Alle fertig!'); end; |
Das Programm hängt sich aber wegen der repeat-Schleife auf. Weiß jemand wie man das besser machen kann?
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 24.09.07 11:38
Moin!
Hendi48 hat folgendes geschrieben: | | Das Programm hängt sich aber wegen der repeat-Schleife auf. Weiß jemand wie man das besser machen kann? |
Probier das mal so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| function AllThreadsReady: Boolean;
var
i: Integer;
begin
Result := FALSE; for i := 0 to High(sizethreaddone) do
if (NOT sizethreaddone[i]) then
Exit;
Result := TRUE;
end; |
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Hendi48 
      
Beiträge: 271
|
Verfasst: Mo 24.09.07 11:46
Hm, es stockt immer noch, liegt das vielleicht daran das die Array 999 Booleans hat und es werden z.B. nur so 80 benutzt, ist dann der Rest automatisch True / False?
Edit: ich hab die Array jetzt dynamisch gemacht. Woher weiß ich denn ob die von Anfang an False oder True ist?
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 24.09.07 11:57
Moin!
Hendi48 hat folgendes geschrieben: | Hm, es stockt immer noch, liegt das vielleicht daran das die Array 999 Booleans hat und es werden z.B. nur so 80 benutzt, ist dann der Rest automatisch True / False?
Edit: ich hab die Array jetzt dynamisch gemacht. Woher weiß ich denn ob die von Anfang an False oder True ist? |
 Du weißt, was du tust?
Generell: Der Inhalt von dynamisch angelegten Variablen (also auch Arrays) ist "zufällig" und muss von dir erst initialisiert werden, also mit einem bestimmten Wert vorbelegt werden.  (Ausnahme: Klasseninstanzen werden automatisch mit 0 initialisiert)
Aber mal ein anderer Ansatz zu deiner Thread-Geschichte: Mach doch einfach eine Integer-Zählervariable, die du bei Programmstart auf 0 setzt. Für jeden gestarteten Thread zählst du 1 drauf, im OnTerminate des Threads ziehst du eins wieder ab. Wenn der Zähler 0 ist, läuft kein Thread mehr!
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Hendi48 
      
Beiträge: 271
|
Verfasst: Mo 24.09.07 12:00
Ah, raffiniert..Danke, ich probiers mal!
Edit:
So das mit dem erhöhen und verringern geht, am Ende ist die Zahl wieder 0. Aber das mit der repeat-schleife klappt nicht, das Prog bleibt immer hängen..was kann ich sonst noch nehmen?
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Mo 24.09.07 12:28
Wie narsens schon so leicht erwähnt hat besitzt jeder Thread ein Event namens OnTerminate welches Synchron aufgerufen wird. Das Einzige was du tun musst und solltest ist dieses Event bei jedem Thread zu setzen. In dieser Methode verringerst du den Referenzzähler und sobald er 0 erreicht hat löst du deine entsprechende Aktion aus. Also der Dialog.
Ich weiß allerdings nicht wie der Rest aussieht aber solch eine Repeatschleife wie du sie hast braucht man normal gar nicht. Von daher vergiss das vollkommen und ändere es so um, dass du informiert wirst. Also via OnTerminate. Damit das OnTerminate aufgerufen wird musst du nur Execute verlassen und gut.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Hendi48 
      
Beiträge: 271
|
Verfasst: Mo 24.09.07 12:57
Ja, hab ich ja. In Destroy hab ich es wieder um 1 senken lassen. Am Ende ist der Wert auch wieder 0, nur ich weiß nich wie ich dem Prog sagen soll das es nichts tun soll bis das halt 0 ist. Mit while geht es auch nicht - das Programm hängt.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 24.09.07 13:12
Moin!
Hendi48 hat folgendes geschrieben: | | Ja, hab ich ja. In Destroy hab ich es wieder um 1 senken lassen. |
Nein, hast du offensichtlich nicht.  Du sollst im OnTerminate-Ereignis des Threads den RefCounter runterzählen, damit das synchronisiert abläuft!
Hendi48 hat folgendes geschrieben: | | Am Ende ist der Wert auch wieder 0, nur ich weiß nich wie ich dem Prog sagen soll das es nichts tun soll bis das halt 0 ist. Mit while geht es auch nicht - das Programm hängt. |
Klar darfst du nicht mit einer while-Schleife das Programm "anhalten". Konkreter: du wartest gar nicht aktiv darauf, sondern lässt dich durch das OnTerminate der Threads benachrichtigen. In dieser Ereignisbehandlungsmethode prüfst du einfach jedes mal, wenn ein Thread terminiert, ob es der Letzte war (RefCount = 0?), wenn ja, machst du das, was dann passieren soll.
Mir scheint, es würde dir sehr gut tun, wenn du mal ein paar Tuts zum Thema Threads durchziehst!
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Hendi48 
      
Beiträge: 271
|
Verfasst: Mo 24.09.07 13:37
| Zitat: |
Mir scheint, es würde dir sehr gut tun, wenn du mal ein paar Tuts zum Thema Threads durchziehst!
|
Ja das finde ich auch..nur ich finde keine guten..Kennst du eins?
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 24.09.07 13:47
Moin!
Hab nix bei der Hand, aber die Suche lieferte in 10 Sek. dieses Tut.  Da es von Luckie ist, schätze ich es mal qualitativ hoch ein; hab´s mir aber selbst noch nicht durchgelesen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 24.09.07 13:54
Ich hab mein bescheidenes Thread-Wissen aus dem Tutorial von Luckie und kann es nur weiterempfehlen. 
_________________ We are, we were and will not be.
|
|
dummzeuch
      
Beiträge: 593
Erhaltene Danke: 5
Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
|
Verfasst: Mo 24.09.07 20:12
Narses hat folgendes geschrieben: | | Aber mal ein anderer Ansatz zu deiner Thread-Geschichte: Mach doch einfach eine Integer-Zählervariable, die du bei Programmstart auf 0 setzt. Für jeden gestarteten Thread zählst du 1 drauf, im OnTerminate des Threads ziehst du eins wieder ab. Wenn der Zähler 0 ist, läuft kein Thread mehr! :idea: ;) |
OnTerminate wird doch noch vom Thread selbst ausgefuehrt, oder?
Dann kann das schiefgehen, wenn mehrere Threads gleichzeitig fertig werden:
* Thread1 liest die Variable
* Thread2 liest die Variable
* beide decrementieren den Wert
* Thread1 schreibt die Variable
* Thread2 schreibt die Variable
Ergebnis: Die Variable wird nur um 1 verringert, obwohl zwei Threads beendet wurden.
Loesungen:
1. Critical Section
2. InterlockedDecrement
twm
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 24.09.07 21:18
Moin!
dummzeuch hat folgendes geschrieben: | | OnTerminate wird doch noch vom Thread selbst ausgefuehrt, oder? |
Nein, wird es nicht, siehe DOH.  Geht also genau so ohne "Verrenkungen".
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
dummzeuch
      
Beiträge: 593
Erhaltene Danke: 5
Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
|
Verfasst: Mo 24.09.07 21:56
Narses hat folgendes geschrieben: | dummzeuch hat folgendes geschrieben: | | OnTerminate wird doch noch vom Thread selbst ausgefuehrt, oder? |
Nein, wird es nicht, siehe DOH. :les: Geht also genau so ohne "Verrenkungen". ;) |
DOH? Delphi Online Hilfe?
Seit Delphi 2005 schaue ich da lieber in den VCL/RTL Sourcecode. Die Hilfe ist einfach zu schlecht geworden (naja, immerhin wird es seit Delphi 2007 wieder besser).
Aber Du hast recht: doTerminate ruft CallTerminate via Synchronize auf. Man lernt doch immernoch was dazu.
twm
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 24.09.07 23:29
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|