Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi bei mehreren threads reagiert form1 nicht (https://www.delphipraxis.net/69062-bei-mehreren-threads-reagiert-form1-nicht.html)

th_bone 9. Mai 2006 18:15


bei mehreren threads reagiert form1 nicht
 
Hi,

mein testprog soll mehrere threads gleichzeitig abarbeiten und dabei
den zähler im memo ausgeben.. das funktioniert soweit auch -

ABER sobald ich mehr als einen thread starte kann ich
die form bis alle threads abgearbeitet sind nicht mehr
bewegen...

bei einem einzelnen thread funzt es aber ohne Probleme :gruebel:

Danke für die Hilfe

Ralf

hier der code:

Delphi-Quellcode:
  Tmythread = class(TThread)
    tcount: integer;
    protected
     procedure execute; override;
     procedure display;
  end;

var
  Form1: TForm1;
  mythr: array[0..5] of TMyThread;
  ithread: integer;

implementation

{$R *.dfm}

procedure Tmythread.display;
begin
 form1.Memo1.Lines.Add(inttostr(tcount));
end;

procedure tmythread.Execute;
begin
  tcount:=1;
  repeat
   synchronize(display);
   inc(tcount);
  until tcount>1000;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  for ithread:=0 to 5 do begin
    mythr[ithread]:= tmythread.create(true);
    mythr[ithread].FreeOnTerminate:=true;
    mythr[ithread].resume;
  end;
end;

th_bone 15. Mai 2006 09:21

Re: bei mehreren threads reagiert form1 nicht
 
Hi,

keiner eine Idee ? Ich komme hier nicht weiter .. die Form sollte sich doch eigntlich bei
Verwendung von Threads und Synchronize(Display) jederzeit bewegen lassen oder habe ich
hier einen Denkfehler ?

Die Threads werden parallel abgearbeitet (was ich anhand der Zahlen im Memo sehen kann)
aber der Hauptthread von Form1 scheint durch synchronize(Display) blockiert zu werden :gruebel:

Danke

Ralf

himitsu 15. Mai 2006 11:30

Re: bei mehreren threads reagiert form1 nicht
 
Bei synchronize; wird ja der Hauptthread solange angehalten, bis die damit aufgerufene Funktion beendet ist ... ich vermute einfach mal, daß nun die "vielen" Threads einfach zuschnell den Hauptthread sperren, so das dieser keine Chance bekommt irgendwas abzuarbeiten.

Versuch mal Forlgendes:
Delphi-Quellcode:
procedure tmythread.Execute;
begin
  tcount:=1;
  repeat
   synchronize(display);
   sleep(100); // ein bissl Zeit für'n Hauptthread
   inc(tcount);
  until tcount>300;
end;
und bei "echt" vielen Thread muß (wenn's klapt) die Zeit aber vergrößert werden, da sie sich ja im Durchschnitt aufteilt ... also bei 50 Threads bleiben (100 / 50 = 2) ja wiederum nur noch durschschnittlich 2 ms Zeit, in denen der Hauptthread was machen kann.

th_bone 15. Mai 2006 11:54

Re: bei mehreren threads reagiert form1 nicht
 
Hi,

Deine Vermutung scheint zu stimmen - mit dem eingebauten sleep funktioniert es - obwohl ich dachte, dass bei der Verwendung von threads dieses Problem nicht auftaucht, da jeder auch der Hauptthread seinen Anteil an der Zeitscheibe erhält - die threads haben ja dieselbe
Priorität - na ja wieder was dazugelernt...

Danke

Ralf

Olli 15. Mai 2006 11:59

Re: bei mehreren threads reagiert form1 nicht
 
Da du nur ganz einfach Integers weitergibst, warum verwendest du nicht PostMessage um den Integer ans Fenster zu schicken? Ist doch "sparsamer" und allemale bequemer als ständig mit Synchronize rumzuwerkeln.

PostMessage statt SendMessage, weil ersteres nicht blockt.

himitsu 15. Mai 2006 12:15

Re: bei mehreren threads reagiert form1 nicht
 
Zitat:

Zitat von th_bone
Deine Vermutung scheint zu stimmen - mit dem eingebauten sleep funktioniert es - obwohl ich dachte, dass bei der Verwendung von threads dieses Problem nicht auftaucht, da jeder auch der Hauptthread seinen Anteil an der Zeitscheibe erhält

Das stimmt ja schon, aber das Synchronize muß ja irgendwie dafür sorgen, daß der Hauptthread nichts macht, wärenmd es arbeitet (wegen der Zugriffsprobleme).

Man könnte ja auch nu das INC selber locken und vom Haupthread (in 'ner Schleife auslesen)

Delphi-Quellcode:
procedure tmythread.Execute;
begin
  tcount:=1;
  repeat
   InterlockedInc(tcount); // ich glaub so hies das
  until tcount>1000;
end;

// entweder im Hauptthread
//
// oder in ähnlicher Weise in einem Nebenthread,
// der als Einziger auf den Hauptthread zugreift
While ... do Begin
  Label1.Caption := IntToStr(mythread.tcount);
  Application.ProgresMessages;
  Sleep(100);
End;

SirThornberry 15. Mai 2006 12:20

Re: bei mehreren threads reagiert form1 nicht
 
Die beste Variante (wie bereits gepostet) erscheint mir hier auch die Verwendung von PostMessage. Und das der Hauptthread nix mehr macht ist wirklich kein Wunder. Denn durch die vielen Threads und die Verwendung von Syncronize kommt der Hauptthread gar nicht mehr dazu was zu machen da ständig irgend ein Thread ein syncrones Arbeiten erzwingt. Da kann man die Threads auch gleich weg lassen. Oder eben PostMessage verwenden.

himitsu 15. Mai 2006 12:35

Re: bei mehreren threads reagiert form1 nicht
 
Eine andere "einfach" Lösung ist halt, statt dem Sleep (von oben) einfach etwas mehr Code einzufügen ... denn wenn zwischen den einzelnen aufrufen von SYNCHRONIZE genug Zeit vergeht, dann würde es ja dennoch "laufen"

Delphi-Quellcode:
procedure tmythread.Execute;
begin
  tcount:=1;
  repeat
   synchronize(display);
   ... // viel Rechenzeit
  until tcount>1000;
end;

procedure tmythread.Execute;
begin
  tcount:=1;
  repeat
   //if display and $FF = 1 then synchronize(display);
   if display mod 256 = 1 then synchronize(display); // mit AND isses schneller
   ... // nich ganz so viel Rechenzeit
  until tcount>1000;
end;
// die 256/$FF sind nur als Beispiel und müßten entsprechend angepasst werden ;)

SirThornberry 15. Mai 2006 12:39

Re: bei mehreren threads reagiert form1 nicht
 
die Frage ist ob das Syncronize notwendig ist wenn man nur einen Integer übermitteln will den man mit Syncronize übermitteln kann. Alternativ könnte man auch noch einen Timer einbauen und im Timer-Event die Werte der Threads abfragen und ins Memo packen.

himitsu 15. Mai 2006 12:52

Re: bei mehreren threads reagiert form1 nicht
 
Zitat:

Zitat von SirThornberry
die Frage ist ob das Syncronize notwendig ist wenn man nur einen Integer übermitteln will den man mit Syncronize übermitteln kann. Alternativ könnte man auch noch einen Timer einbauen und im Timer-Event die Werte der Threads abfragen und ins Memo packen.

Syncronize hatte ich früher oft verwendet und keine Probleme gehabt, wenn dazwischen halt nur genug Zeit blieb (außerdem muß man den Status ja nich Millisekündlich dem User mitteilen ... sooo schnell gugt der eh nicht :roll: )

Das mit dem Timer ist eigentlich mit am Besten, um einem User den Status mitzuteilen (denk ich) ... die Anzeige kommt schon regelmäßig, egal wie schnell der PC die Schleife abarbeitet (man braucht da also nichts mehr steuern/nachregeln)

Hatte da mal soein Konstrukt.
Delphi-Quellcode:
While ... do Begin;
  ...
  If GetTickCount - Timer > 1000 Then Begin
    Timer := GetTickCount;
    ... // Status ausgeben
  End;
End;
Da isses halt Einfacher und Sparrsamer, wenn von außen angefragt wird :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:58 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