Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Thread will nicht synchron schwimmen? (https://www.delphipraxis.net/164110-thread-will-nicht-synchron-schwimmen.html)

Edlmann 28. Okt 2011 18:29

Thread will nicht synchron schwimmen?
 
Hey DP,

Ich versuche grad zum xten Mal, mein Projekt Shapewars auf eine Multithread-anwendung umzustellen. Hierfür möchte ich zunächst die Partikeleffekte und deren Berechnung in einen Thread auslagern. Hierfür hab ich mir einen eigenen TThread abgeleitet, im Moment mit folgendem Code:

Delphi-Quellcode:
type
  TWorkerthread = class(TThread)
  private
  protected
    procedure Execute; override;
  public
    procedure SetJob(Val: Boolean);
    function GetJob: Boolean;
  end;

var
  Fin, HasJob: Boolean;



implementation

uses Main;

function TWorkerthread.GetJob: Boolean;
begin
  NotifText := BoolToSTr(Fin, true);
  NotifTime := 100;
  Result := not Fin;
end;

procedure TWorkerthread.SetJob(Val: Boolean);
begin
  HasJob := Val;
end;

procedure TWorkerthread.Execute;
begin
  while True do
  begin
  if HasJob then
  begin
  Fin := False;
  // Wenn Partikel eingeschaltet sind
  if RenderPartikel then
  begin
  MovePartikel;
  end;
  HasJob := false;
  Fin := true;
  end
  else
  Sleep(1);
  end;
end;
Die Variable Fin hab ich erstmal nur eingeführt, um zu schauen ob er so macht was er soll. Der Thread ist also eine Endlosschleife, die immer wieder nachschaut ob sie die Partikel wieder um einen Schritt weiterbewegen soll (Geschiet mittels MovePartikel) oder eben nicht. Jeden Frame soll also optimalerweise einmal ein Job ausgeführt werden. Nun möchte ich in der Hauptschleife des Spiels (Die über den VCL-Thread läuft) auf die Fertigstellung des Jobs warten, und zwar mittels

Delphi-Quellcode:
while AWorker.GetJob do
  begin
  sleep(1);
  Application.ProcessMessages;
  end;
Wobei AWorker mein Thread ist. Allerdings erscheint so die Form gar nicht mehr, ich muss das Spiel über den TaskManager killen, und lass ich es erst laufen bleibt die Prozessorauslastung bei 0 (also warten beide Thread gerade...), doch anscheinend kommt er aus der Schleife nicht vernünftig wieder raus -.-"

Ich hoffe mir kann jemand weiterhelfen, bin auch nach mehreren Tutorials zu Threads auf keine Lösung gestoßen,
Lg,
Edlmann

Sir Rufo 28. Okt 2011 19:14

AW: Thread will nicht synchron schwimmen?
 
1. Das Verwenden von globalen Variablen ist fast immer falsch
2. Der Austausch von Thread-Status-informationen über eine globale Variable ... geht gar nicht
3. Eigenschaften in einem Thread einfach so zu ändern ein NoGo
4. Einen Thread in einer Endlosschleife zu parken ... besser so, dann kann man den auch mal vernünftig beenden
Delphi-Quellcode:
procedure MyThread.Execute;
begin
  while not Terminated do
    begin
      ...
    end;
end;
Schau dir mal hier im Forum die Informationen zum Thema Hier im Forum suchenThread und Hier im Forum suchenCriticalSection an.

Edlmann 29. Okt 2011 11:55

AW: Thread will nicht synchron schwimmen?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1133266)
1. Das Verwenden von globalen Variablen ist fast immer falsch
2. Der Austausch von Thread-Status-informationen über eine globale Variable ... geht gar nicht
3. Eigenschaften in einem Thread einfach so zu ändern ein NoGo
4. Einen Thread in einer Endlosschleife zu parken ... besser so, dann kann man den auch mal vernünftig beenden
Delphi-Quellcode:
procedure MyThread.Execute;
begin
  while not Terminated do
    begin
      ...
    end;
end;
Schau dir mal hier im Forum die Informationen zum Thema Hier im Forum suchenThread und Hier im Forum suchenCriticalSection an.

Vielen Dank schonmal, damit ist wenigstens der Stil schonmal besser ;)
Das mit den globalen Variablen und dem not Terminated ist mir auch direkt nach dem Posten aufgefallen, ist schon geändert. Funktioniert allerdings noch immer nicht.

Was genau meinst du mit Punkt 3?

grl 29. Okt 2011 15:41

AW: Thread will nicht synchron schwimmen?
 
Edlmann,

also, mal abgesehen von dem was Sir Rufo schon angeführt und der Tatsache, daß du keinerlei Synchronisation hast (Stichwort CriticalSection), sollte das schon irgendwie hinhauen.

Um da einen Fehler zu finden musst du uns schon mit vollständigem Sourcecode füttern.

Mach mal was wirklich kompilierbares (was z.B. ist das NotifText und NotifTime, wozu sind die gut?) und wo ist Renderpartikel und Movepartikel definiert? Sind das lauter Thread-Safe implementierte Dinge?

Ich stell jetzt einfach mal eine Vermutung in den Raum: in Renderpartikel oder Movepartikel machst du einen VCL-Zugriff und das kracht...

Gruß
Luggi

Furtbichler 29. Okt 2011 19:57

AW: Thread will nicht synchron schwimmen?
 
Lustig, wenn man 'Workerthread' in die Suchfunktion eingibt, findet man sogar was.

Edlmann 29. Okt 2011 21:42

AW: Thread will nicht synchron schwimmen?
 
Zitat:

Zitat von grl (Beitrag 1133405)
Edlmann,

also, mal abgesehen von dem was Sir Rufo schon angeführt und der Tatsache, daß du keinerlei Synchronisation hast (Stichwort CriticalSection), sollte das schon irgendwie hinhauen.

Um da einen Fehler zu finden musst du uns schon mit vollständigem Sourcecode füttern.

Mach mal was wirklich kompilierbares (was z.B. ist das NotifText und NotifTime, wozu sind die gut?) und wo ist Renderpartikel und Movepartikel definiert? Sind das lauter Thread-Safe implementierte Dinge?

Ich stell jetzt einfach mal eine Vermutung in den Raum: in Renderpartikel oder Movepartikel machst du einen VCL-Zugriff und das kracht...

Gruß
Luggi

RenderPartikel => Boolean der bestimmt ob Partikeleffekte Gerendert werden sollen
MovePartikel => Arbeitet eine TList mit Partikeln durch, auf die der VCL-Thread nicht zugreift. Somit ist eine CriticalSection nicht nötig.
Ich versteh auch nicht wieso es nicht funktioniert, seit ich die beiden Booleans Fin und HasJob in die klasse des Threads verlagert hab kommen nur AV's bei jedem Aufruf...werd ich mir Morgen in wachem Zustand alles nochmal zu Gemüt führen und nach dem Fehler suchen...das ist das erste Mal das ich Threads benutze, doch eigentlich dachte ich ich hätte genug Tutorials durch um das ganze einigermaßen zu verstehen...mal wieder Fehlanzeigen :D

Zitat:

Zitat von Furtbichler (Beitrag 1133462)
Lustig, wenn man 'Workerthread' in die Suchfunktion eingibt, findet man sogar was.

Ja, darauf bin ich auch gestoßen. Ist aber ziemlicher Overkill für meine Anwendung.

grl 29. Okt 2011 23:17

AW: Thread will nicht synchron schwimmen?
 
Edlmann,

ich kanns nur nochmal sagen - stell ein compilierbares, vollständiges Beispiel ein, bei dem man den Effekt sehen kann. Dann können wir dir sicher helfen.

Nachdem meine Kristallkugel im Wochenende ist, ist es sonst extrem schwierig.

Gruß
Luggi

BUG 30. Okt 2011 00:59

AW: Thread will nicht synchron schwimmen?
 
Hi,

erst möchte ich dir mal etwas Lesestoff geben: http://wiki.delphigl.com/index.php/S...mlung#Partikel

Dann zu deinem Threadproblem: Bei einem Partikelsystem fallen imho einige Beschränkungen weg, die bei normalen Aufgaben bestehen. Es sollte reichen sicherzustellen das nur ein Thread in ein Partikel schreibt. Das kannst du machen indem du zB jedem Partikelbuffer einem Thread zuteilst und die neuertstellten Partikel auf die Buffer verteilst (das musst du dann synchronisieren, wenn du aber im Thread keine Partikel erstellst, sollte zB das suchen toter Partikel auch asynchron möglich sein). Da es aber nicht schlimm ist, wenn mal ein Partikel ein paar Pixel daneben gezeichnet wird, musst du das Auslesen der Buffer zum Zeichnen nicht synchronisieren.

Die einzige Schwierigkeit sehe ich darin die Zeiten zu synchronisieren, da Partikel aber nur Grafik sind muss auch das nicht perfekt sein.

Furtbichler 30. Okt 2011 09:18

AW: Thread will nicht synchron schwimmen?
 
Zitat:

Zitat von Edlmann (Beitrag 1133476)
Zitat:

Zitat von Furtbichler (Beitrag 1133462)
Lustig, wenn man 'Workerthread' in die Suchfunktion eingibt, findet man sogar was.

Ja, darauf bin ich auch gestoßen. Ist aber ziemlicher Overkill für meine Anwendung.

Durch Studium des Overkills hättest Du Einiges an Problemen bei deiner Implementierung vermieden.

Edlmann 30. Okt 2011 14:25

AW: Thread will nicht synchron schwimmen?
 
Zitat:

Zitat von grl (Beitrag 1133487)
Edlmann,

ich kanns nur nochmal sagen - stell ein compilierbares, vollständiges Beispiel ein, bei dem man den Effekt sehen kann. Dann können wir dir sicher helfen.

Nachdem meine Kristallkugel im Wochenende ist, ist es sonst extrem schwierig.

Gruß
Luggi

Wird schwierig, ich werds aber mal versuchen, da was kompilierbares auf die Beine zu stellen.

Zitat:

Zitat von BUG (Beitrag 1133492)
Hi,

erst möchte ich dir mal etwas Lesestoff geben: http://wiki.delphigl.com/index.php/S...mlung#Partikel

Dann zu deinem Threadproblem: Bei einem Partikelsystem fallen imho einige Beschränkungen weg, die bei normalen Aufgaben bestehen. Es sollte reichen sicherzustellen das nur ein Thread in ein Partikel schreibt. Das kannst du machen indem du zB jedem Partikelbuffer einem Thread zuteilst und die neuertstellten Partikel auf die Buffer verteilst (das musst du dann synchronisieren, wenn du aber im Thread keine Partikel erstellst, sollte zB das suchen toter Partikel auch asynchron möglich sein). Da es aber nicht schlimm ist, wenn mal ein Partikel ein paar Pixel daneben gezeichnet wird, musst du das Auslesen der Buffer zum Zeichnen nicht synchronisieren.

Die einzige Schwierigkeit sehe ich darin die Zeiten zu synchronisieren, da Partikel aber nur Grafik sind muss auch das nicht perfekt sein.

Hab ich mir schon durchgelesen, das GPU-System ist mir noch deutlich zu hoch, und das für ältere Hardware hilft mir beim meinem Problem nicht weiter, so ähnlich arbeitet mein System schon ;)

Zitat:

Zitat von Furtbichler (Beitrag 1133504)
Durch Studium des Overkills hättest Du Einiges an Problemen bei deiner Implementierung vermieden.

Nein, nicht wirklich. Ich habe die Basis-Struktur von Threads schon verstanden und auch des öfteren schon benutzt (z.B. bei nem Downloader), bekomme nur die Synchronisation nicht vernünftig hin...


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:32 Uhr.
Seite 1 von 3  1 23      

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