Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   WorkerThread.Execute arbeitet keine procedure ab ? (https://www.delphipraxis.net/170725-workerthread-execute-arbeitet-keine-procedure-ab.html)

MrMooed 30. Sep 2012 20:31

Delphi-Version: 2007

WorkerThread.Execute arbeitet keine procedure ab ?
 
'Nabend

Ich habe mich wegen eines Projektes mal an das Thema Multithreading gewagt :?

Nun habe ich das Problem, dass ich dem WorkerThread Parameter zum rechnen übergebe, aber sobald ich Worker.Resume auf 'True' setzte passiert garnichts. Kann es dadran liegen, dass ich in der .Execute eine andere procedure starte (die die eigentliche Berechnung durchführt) ?

Hier mal ein wenig Code:
Aufruf in main-unit:
Delphi-Quellcode:
procedure TForm1.Vollbild1Click(Sender: TObject);
var
  i: Integer;
  Thread: Array of WorkerThread;
begin
  SetLength(Thread, GetCPUCount);
  for i:=0 to Length(Thread)-1 do begin
    Thread[i] := WorkerThread.create(true);
    Thread[i].ThreadCount := GetCPUCount;
    Thread[i].Y_Min := Y_Min;
    Thread[i].Y_Max := Y_Max;
    Thread[i].X_Min := X_Min + i * (X_Min + X_Max) / GetCPUCount;
    Thread[i].X_Max := Thread[i].X_Min + i * (X_Min + X_Max) / GetCPUCount;
    Thread[i].Hoehe := Form1.Height;
    Thread[i].Breite := Form1.Width DIV GetCPUCount;
    Thread[i].Resume;
    end;
end
Bei der WorkerThread.Execute macht es keinen Unterschied ob ich die procedure damit aufrufe, oder ob ich sie direkt dadrin berechne o.o

daywalker9 30. Sep 2012 20:46

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
Wie sieht denn dein WorkerThread aus?

MrMooed 1. Okt 2012 14:21

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
Zitat:

Zitat von daywalker9 (Beitrag 1185159)
Wie sieht denn dein WorkerThread aus?

Ist ein wenig lang, aber habe keine Ahnung ob / wie man hier einen Spoiler einfügt :oops:

Delphi-Quellcode:
unit mWorkerThread;

interface

uses
  classes, Graphics;

type
  WorkerThread = class(TThread)
  protected
    procedure Execute; override;
    procedure berechnePixel();
    function rechne(X_Ko, Y_Ko: double): Integer;
  public
    Bild : TBitMap;
    X_Min, Y_Min, X_Max, Y_Max: double;
    ThreadCount, Hoehe, Breite: Integer;
  end;

implementation

function WorkerThread.rechne(X_Ko, Y_Ko: double): Integer;
var
  i: Integer;
  nX, nY, X, Y, A: double;
begin
  i := 0;
  X := 0;
  Y := 0;
  while (i < 100) and (A < 4) do begin
    nX := (X*X) - (Y*Y) + X_Ko;
    nY := 2 * X * Y + Y_Ko;
    X := nX;
    Y := nY;
    A := X*X + Y*Y;
    Inc(i);
    end;
    result := i;
end;

procedure WorkerThread.berechnePixel();
var
   x, y: Integer;
   faktorX, faktorY, tmp: double;
begin
    x := 0;
    tmp := Y_Min;
    Bild := TBitMap.Create;
    Bild.Width := Hoehe;
    Bild.Height := Breite;
    faktorX := (Abs(x_Min)+Abs(x_Max)) / Bild.Width;
    faktorY := (Abs(y_Min)+Abs(y_Max)) / Bild.Height;
    while (x_Min <= x_Max) do begin
      y := 0;
      while (y_Min <= y_Max) do begin
        case rechne(x_Min, y_Min) of
          0..10: Bild.Canvas.Pixels[x,y] := clBlack;
          11..20: Bild.Canvas.Pixels[x,y] := clOlive;
          21..30: Bild.Canvas.Pixels[x,y] := clYellow;
          31..40: Bild.Canvas.Pixels[x,y] := clLime;
          41..50: Bild.Canvas.Pixels[x,y] := clGreen;
          51..60: Bild.Canvas.Pixels[x,y] := clAqua;
          61..70: Bild.Canvas.Pixels[x,y] := clBlue;
          71..80: Bild.Canvas.Pixels[x,y] := clNavy;
          81..90: Bild.Canvas.Pixels[x,y] := clPurple;
          else   Bild.Canvas.Pixels[x,y] := $000000;
        end;
        y_Min := y_Min + faktorY;
        Inc(y);
      end;
      y_Min := tmp;
      x_Min := x_Min + faktorX;
      Inc(x);
    end;
end;

procedure WorkerThread.Execute;
begin
  berechnePixel;
end;

end.

daywalker9 1. Okt 2012 14:32

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
Hast Du denn schon mal einen BReakpoint in WorkerThread.Execute gesetzt, um zu schauen, ob Du da rein kommst?

DeddyH 1. Okt 2012 14:34

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
Und wozu ist die Bitmap gut, die nur erzeugt, aber nirgends dargestellt/gespeichert/freigegeben wird?

Klaus01 1. Okt 2012 14:37

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
In der Methode "darstellen", wie und wo soll denn da ewtas dargestellt werden.
Es wird ein Instanz von TBitmap erzeugt - mit dem Inhalt etwas angestellt/berechnet.
Das war es dann schon.
Die Instannz wird nicht freigegeben noch wird etwas zu Ausgabe gebracht.

Wenn Du etwas in Deiner Hauptform darstellen willst, solltest Du dich
mit critcal section und/oder synchronize beschäftigen.

Grüße
Klaus

DeddyH 1. Okt 2012 14:39

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
Sag ich doch :)

MrMooed 1. Okt 2012 14:45

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
also zunäschsteinmal hatte ich es mir so vorgestellt (deswegen wurde Bild public deklariert) dass ich mir in meiner Hauptunit das Bild hole, sobald der Thread suspended ist.
Freigegeben wird der Speicher doch sowieso, sobald der Thread terminiert wurde oder habe ich das falsch verstanden ?

Und mit dem Debugger bin ich trotz Haltepunkt nicht in dem Thread gelandet - er bekommt alle Atribute, aber startet dann einfach nicht :gruebel:

//Edit: ok 'darstellen' ist wirklich ein unpassender Name dafür, kam noch aus der Zeit wo ich einen Thread hatte der dann damit direkt gezeichnet hat. :D Werde es umbenennen.

himitsu 1. Okt 2012 15:00

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
Das "darstellen" sollte wohl eher sowas wie "(be)arbeiten" heißen.

PS: statt über das langame Delphi-Referenz durchsuchenTCanvas.Pixels zu gehn, könnte man sich eventuell auch mal mit Delphi-Referenz durchsuchenTCanvas.Scanline beschäftigen.
Jenachdem wie langsam/schnell das "rechne" ist, könnte man sich die Threads auch sparen.


Bezüglich deinem "rechne":
- Wo hast du denn A initialisiert?
Das sollte dir der Compiler auch melden (falls man sich mal die Compilermeldungen durchliest), denn du wertest das schon aus, noch bevor A einen definierten Wert hat.
Und ohne Initialisierung sind lokale Variablen potentiell erstmal mit Zufallswerten befüllt.

oder man stellt das ein bissl um (das A erst auswerten, nachdem es berechnet wurde, bzw. gleich die Auswertung und Berechnung zusammenlegen und sich A sparen)
Delphi-Quellcode:
function WorkerThread.rechne(X_Ko, Y_Ko: double): Integer;
var
  nX, nY, X, Y: double;
begin
  Result := 0;
  X := 0;
  Y := 0;
  repeat
    nX := Sqr(X) - Sqr(Y) + X_Ko;
    nY := 2 * X * Y + Y_Ko;
    X := nX;
    Y := nY;
    Inc(Result);
  until (Result >= 100) or (Sqr(X) + Sqr(Y) >= 4);
end;
[edit]
bissl lahm


Wird das Execute, laut Debugger, nicht sofort im ".Resume" ausgeführt, oder überhaupt nicht?
Der Thread wird (vorallem im Debugger) etwas verzägert gestartet.

MrMooed 1. Okt 2012 15:09

AW: WorkerThread.Execute arbeitet keine procedure ab ?
 
:oops: *Im Erdboden versink* - dachte dass ich es mir sparen kann zu initialisieren, da ihm ja direkt ein Wert zugewiesen wird .. aber vorher prüft er ja das A :wall: hätte bestimmt einiges an Zeit gebraucht um ein Fehlverhalten dadurch nachzuvollziehen :roll:

Jedenfalls habe ich immer noch keinen blassen Schimmer warum er den Thread nicht startet. Kann Delphi so schlau sein, dass es den Thread "wegoptimiert", da ich zu Testzwecken noch nicht auf WorkerThread.Bild zugreife :?: Werde es mal testen

//Edit:
Zitat:

Zitat von himitsu (Beitrag 1185287)
Wird das Execute, laut Debugger, nicht sofort im ".Resume" ausgeführt, oder überhaupt nicht?
Der Thread wird (vorallem im Debugger) etwas verzägert gestartet.

es wurde überhaupt nicht ausgeführt. Totenstille nach dem ich die Werte übergeben habe.
Und es scheint tatsächlich so zu sein, dass Delphi mir den Thread wegoptimiert hat, da ich das Bild nicht weiter benutzt habe - welch eine schlaue Software ich da doch benutze :coder2:


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