[delphi7]Wachten tot alle threads klaar zijn.

Pagina: 1
Acties:
  • 116 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Topicstarter
Na een tijdje van inactiviteit heb ik de ontwikkeling van mijn CPU benchmarktapplicatie weer eens opgepakt. Nu wil ik met de huidige ontwikkelingen (HT, dual cpu systemen, etc.) ook een multithreaded test. Dat heb ik netjes aan de gang, de user kan het aantal threads opgeven (standaard 2) en die worden gewoon gestart. Daarmee gaat het allemaal goed, alleen ik wil de knop waarmee de test wordt gestart disabled houden totdat alle threads klaar zijn.

Ik heb verschillende stukjes code geprobeerd, waaronder getExitCodethread() uit dit topic, en WaitForMultipleObjects() uit dit artikel.

Met WaitForMultipleObjects() heb ik de volgende code gebakken:
Delphi:
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
26
27
28
29
procedure TfrmMain.btnStartClick(Sender: TObject);
var test: array of Ttest_thread;
    handles: array of Thandle;
    i: integer;
begin

//lengte van de array's zetten:
setlength(test, strtoInt(maskeditThreads.Text));
setlength(handles, strtoInt(maskeditThreads.Text));

memoTest.Clear;
btnStart.Enabled:=false;
statusBar.SimpleText:= 'Running...';

application.ProcessMessages;

    for i:=0 to (strtoInt(maskeditThreads.Text)-1) do
      begin
        test[i] := Ttest_thread.Create(true);
        test[i].Fmax:= strtoInt(maskeditGenerations.text);
        test[i].Thread_id:=i;
        test[i].FreeOnTerminate:= true;
        test[i].Resume;
        handles[i]:= test[i].Handle;
      end;
WaitForMultipleObjects(i, @handles, True, INFINITE);
btnStart.Enabled:=true;
statusBar.SimpleText:= 'Ready.';
end;


De knop wordt netjes gedisabled maar nooit meer enabled. Als ik een application.messagebox() voor en achter WaitForMultipleObjects() plaats worden die wel alle 2 weergegeven, alleen wordt de laatste meteen na de eerste weergegeven, dus terwijl de threads nog runnen. Hoe komt dit en hoe kan ik ervoor zorgen dat mijn button wel weer enabled wordt op het juiste moment?


MSDN WaitForMultipleObjects() documentatie

[ Voor 7% gewijzigd door AtleX op 12-12-2004 19:41 ]

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Wat geeft WaitForMultipleObjects als resultaat? Zijn je threads niet al gewoon al klaar voordat je die functie aanroept? Hoe ben je daar zo zeker van? De variable i zou ik niet meer gebruiken buiten de for loop. Er is ook geen garantie dat die de max waarde bevat. Maak daar gewoon eens strtoInt(maskeditThreads.Text) van. WaitForMultipleObject blocked de main thread. Zolang dat gebeurd wordt er geen windows message meer afgehandeld en lijkt je applicatie bevroren. Lijkt me niet gewenst. Bovendien heb je ook nog kans dat het INFINITE lang gaat duren. En zodra je een Synchronize gebruikt in je thread heb je een deadlock.

Ik zou je threads een message laten posten naar je form dmv PostMessage waarmee ze aangeven dat ze klaar zijn.

We adore chaos because we like to restore order - M.C. Escher


Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Topicstarter
LordLarry schreef op zondag 12 december 2004 @ 19:24:
Wat geeft WaitForMultipleObjects als resultaat?
Zijn je threads niet al gewoon al klaar voordat je die functie aanroept? Hoe ben je daar zo zeker van?
Als ik die WaitForMultipleObjects()-regel eruit haal wordt mijn knop meteen weer enabled maar lopen mijn threads nog meer dan 1 minuut door. Ze zijn dan dus nog niet klaar.
De variable i zou ik niet meer gebruiken buiten de for loop. Er is ook geen garantie dat die de max waarde bevat. Maak daar gewoon eens strtoInt(maskeditThreads.Text) van.
Done, geen effect.
WaitForMultipleObject blocked de main thread. Zolang dat gebeurd wordt er geen windows message meer afgehandeld en lijkt je applicatie bevroren. Lijkt me niet gewenst. Bovendien heb je ook nog kans dat het INFINITE lang gaat duren. En zodra je een Synchronize gebruikt in je thread heb je een deadlock.
Ik synchronize nergens, mijn threads zijn volledig op zichzelf staand.
Ik zou je threads een message laten posten naar je form dmv PostMessage waarmee ze aangeven dat ze klaar zijn.
Hoe had jij dat in gedachten, want dit snap ik even niet?

In het stukje code dat in mijn startpost staat heb ik een gigantische fout ontdekt:
Delphi:
1
2
3
WaitForMultipleObjects(i, @handles, True, INFINITE);
btnStart.Enabled:=true; //DEZE REGEL BEVATTE ALLEEN btnStart.Enabled;
statusBar.SimpleText:= 'Ready.';


Nu wordt mijn knop dus wel enabled maar dan wel meteen, dus nog voor de threads klaar zijn.

[ Voor 14% gewijzigd door AtleX op 12-12-2004 19:44 ]

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22-07 14:32

alienfruit

the alien you never expected

Misschien handig: Threads en Delphi? Maar zoals LordLarrya l zei je kan ook gebruik maken van een PostMessage waarmee je een custom message stuurt naar het hoofdform. Om te melden dat je al klaar bent, die vervolgens de status-en afhandeld. Dus niet textboxes bewerken vanuit de thread.

Acties:
  • 0 Henk 'm!

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

AtleX schreef op zondag 12 december 2004 @ 19:38:
Als ik die WaitForMultipleObjects()-regel eruit haal wordt mijn knop meteen weer enabled maar lopen mijn threads nog meer dan 1 minuut door. Ze zijn dan dus nog niet klaar.
Ik vroeg hoe je zo zeker weet dat je threads doorlopen. En ik wil graag weten wat het resultaat is van die functie. ik verwacht namelijk een foutcode.
Hoe had jij dat in gedachten, want dit snap ik even niet?
Zie het antwoord van alienfruit en vooral de link.

We adore chaos because we like to restore order - M.C. Escher


Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Topicstarter
Ok, ik heb het. Als mijn threads klaar zijn roepen ze postmessage() en sturen een message. Die message lees ik houdt en als het aantal geposte messages overeen komt met het aantal gestarte threads enable ik mijn knop weer.

LordLarry en alienfruit, bedankt :>

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Uhhh... Dit lijkt me een simpel gevalletje van een counting semafoor. Stel dat je n threads nodig hebt... dan laat je de thread die moet wachten n downs doen op een semafoor (met een startwaarde van 0) en zo gauw een thread klaar is laat je hem een up doen. Op het moment dat alle n ups binnen zijn kan de wachtende thread weer wakker worden en zijn weg vervolgen.

[edit]
Ik heb nog even goed gekeken... maar ik neem aan dat je je gui thread niet wilt laten maffen :P

[ Voor 14% gewijzigd door Alarmnummer op 12-12-2004 20:31 ]


Acties:
  • 0 Henk 'm!

  • jvdmeer
  • Registratie: April 2000
  • Nu online
Kijk eens naar de demo van delphi:
"C:\Program Files\Borland\Delphi7\Demos\Threads\thrddemo.dpr"

Die gebruikt een aparte thread-counter: ThreadsRunning
Pagina: 1