AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread läuft nicht parallel --

Ein Thema von sonny2007 · begonnen am 9. Jan 2014 · letzter Beitrag vom 11. Jan 2014
Antwort Antwort
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 09:30
Hi Leute,

ich sitze jetzt die halbe Nacht und irgendwie werde ich nicht schlau daraus.
Das kenne ich...

Ins Bett gehen... Nach dem 1. Kaffee den Code in die Execute verschieben und feststellen, es war gestern doch zu spät für so eine Routine...

Mavarik
  Mit Zitat antworten Zitat
sonny2007

Registriert seit: 27. Aug 2009
39 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 09:42
hiho,

mmhhhhhh.........

also ich habe es jetzt so abgeändert.

in formCreate
Delphi-Quellcode:
aktScreen1 := TBitmap.Create;
  aktScreen2 := TBitmap.Create;
  suchbild1 := TBitmap.create;
  suchBild2 := TBitmap.Create;

  suchbild1.LoadFromFile('C:\Users\blabla\Pictures\i1.bmp');
  suchBild2.LoadFromFile('C:\Users\blabla\Pictures\2.bmp');
dann der Thread Aufruf vom Button

Delphi-Quellcode:
procedure TfrmMain.searchInventar(Sender: TObject);
begin
  fstarttimer := GetTickCount;
  ScreenCapture(aktScreen1);
  ScreenCapture(aktScreen2);
  ThreadsRunning := 2;

  // Threads erzeugen aber nicht ausführen
  Thread1 := TImageSearch.Create(true);
  Thread1.OnTerminate := ThreadDone1;
  Thread1.Searchbmp.Assign(suchbild1);
  Thread1.screenbmp.Assign(aktScreen1);
  Thread1.NameThreadForDebugging('Thread1');

  Thread2 := TImageSearch.Create(true);
  Thread2.OnTerminate := ThreadDone2;
  Thread2.Searchbmp.Assign(suchbild2);
  Thread2.screenbmp.Assign(aktScreen2);
  Thread2.NameThreadForDebugging('Thread2');

  // Threads starten
  Thread1.start;
  Thread2.start;
end;
Und hier der komplette thread Part

Delphi-Quellcode:
unit imgCompareThread;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ComCtrls,
  Vcl.Menus,Vcl.ImgList,SelectKit,pictureHelper;

type
  TImageSearch = class(TThread)
  private
    fScreenBMP : TBitmap;
    fSearchBMP : TBitmap;
    fxyPoint : Tpoint;
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  public
    //constructor Create(CreateSuspended : boolean ;var SearchBMP,ScreenBMP : TBitmap;var xyPoint : TPoint);overload;
    constructor Create(CreateSuspended: boolean); overload;
    property ScreenBMP : TBitmap read FScreenBMP write FScreenBMP;
    property SearchBMP : TBitmap read FSearchBMP write FSearchBMP;
    property xyPoint : TPoint read fxyPoint write fxyPoint;
  end;

implementation

{ TImageSearch }

procedure TImageSearch.Execute;
var
  x,y: Integer;
  tempBMP : Tbitmap;
  rectSource,rectDest : TRect;
  toBreak : boolean;
  i: Integer;
  k: Integer;
begin
  toBreak := false;
  // ******************************************************************************
  // Inventar oben links suchen
  // ******************************************************************************
  Try
    // Declaration
    tempBMP := Tbitmap.Create;
    tempBMP.Width := FSearchBMP.Width;
    tempBMP.Height := FSearchBMP.Height;
    tempBMP.PixelFormat := FSearchBMP.PixelFormat;
    for x := 0 to FScreenBMP.Width-tempBMP.Width-1 do
      begin
        if toBreak then break;
        for y := 0 to FScreenBMP.Height-tempBMP.Height-1 do
        begin
          // Ausschnittsbereich festlegen
          rectDest := rect(0,0,tempBmp.Width,tempBmp.Height);
          rectSource := rect(x,y,x+tempBmp.Width,y+tempBmp.Height);
          tempBmp.Canvas.CopyMode := cmSrcCopy;
          // Ausschnittsbereich kopieren rectSource
          tempBmp.Canvas.CopyRect(rectDest,ScreenBMP.Canvas,rectSource);
          //imgTemp.Picture.Bitmap.Assign(tempBMP);
          if Compare2Bitmaps(60,FSearchBMP,tempBMP) = ceOK then
            begin
              toBreak := true;
              fxypoint.x := x;
              fxypoint.y := y;
              with Tform.Create(nil) do
                begin
                  FormStyle := fsStayOnTop;
                  Name := 'frmSelection2';
                  Position := poDesigned;
                  left := x-3;
                  top := y-3;
                  Width := 56;
                  Height := 56;
                  borderstyle := bsNone;
                  color := clWhite;
                  for k := 0 to 5 do
                    begin
                      visible := true;
                      sleep(100);
                      visible := false;
                      sleep(100);
                    end;
                  free;
                end;
              break;
            end;
        end;
      end;
  Finally
    tempBMP.Free;
  End;
end;

constructor TImageSearch.Create(CreateSuspended: Boolean);
begin
  fScreenBMP := TBitmap.Create;
  fSearchBMP := TBitmap.Create;
  inherited Create(CreateSuspended);
end;


end.
im OnTerminate wollte ich die XY Points holen doch die geben leider immer null zurück.
Delphi-Quellcode:
Dec(ThreadsRunning);
  xyPoint2 := Thread2.xyPoint;
  showMessage('X2: ' +inttostr(Thread2.xyPoint.X)+' Y2: '+inttostr(Thread2.xyPoint.Y));
Was mache ich da falsch? Wenn ich die Bilder einzeln suche, also ohne Thread gleicher Code, findet er sie einwandfrei.

Die Version von letzter Nacht mach auch alles richtig. Also werte werden richtig zurück gegeben.

Grüße s0n
  Mit Zitat antworten Zitat
sonny2007

Registriert seit: 27. Aug 2009
39 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 09:44
Mal abgesehen von der falschen Verwendung von Threads...

Das Kopieren eines Ausschnitts der ScreenBMP in die tempBmp ist hier der eigentlich bremsende Faktor.
Es erscheint mir sinnvoller die Funktion "Compare2Bitmaps" so anzupassen, dass statt zwei kompletter Bitmaps, nur der angegebene Bereich verglichen wird.

Compare2Bitmaps(80, SearchBMP, ScreenBMP, rectSource);
ich kopiere in die TempBmp einen Ausschnitt des Screens und nur der wird mit dem Suchbitmap verglichen. Verstehe jetzt nicht so ganz wie du es meinst.
Bin für Kritik und Verbesserung jederzeit zu haben ^^

Grüße s0n
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#4

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 09:49
Du weißt dass weder VCL-Zugriffe noch TCanvas threadsave sind?
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
sonny2007

Registriert seit: 27. Aug 2009
39 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 09:53
Deshalb war der Gedanke für jeden Thread unterschiedliche Bitmaps zu verwenden. Das sie nicht Threadsave sind habe ich in der Hilfe gelesen.

Also Thread 1 bekommt screen1 und search1 und thread 2 bekommt screen2 und search2. Somit sollten sich die Canvas doch nicht ins Gehege kommen oder sehe ich das falsch ?

Grüße
s0n
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#6

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 10:11
Leider ist dem nicht so. Ich habe mal ein Microdemo angehängt bei dem ein paar Bitmaps parallel erzeugt `bemalt` und gespeichert werden (Pfad anpassen). Wenn man sich das Ergebnis ansieht wird klar dass Canvas nicht Threadsave ist. Über lock ließe sich das ganze verhindern, aber dann ist der Gewinn durch die Threads ebenfalls weg. Ich weiß ja nicht was genau der Vergleich machen soll, aber über Scanlines (wenn Dir das hilft) sollte es keine Probleme geben.
Angehängte Dateien
Dateityp: zip Demo_Thread_CanvasProblem.zip (3,2 KB, 12x aufgerufen)
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.378 Beiträge
 
Delphi 12 Athens
 
#7

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 10:27
TBitmap und Co. wären Threadsave, wenn sie "unabhängig" verwendet werden und nichts Globales nutzen.

Aber sie verwenden intern weitere Klasseninstanten und da werden vorallen für TFont, TBrush uvm. globale Instanzen verwendet (wenn man selber nichts eigenes angibt und die Werte auf "Standard" läßt)
und da dort überall auf die selben globalen Singletons zugegrifen wird muß es zwangsläufig schief gehn, jenachdem was man mit dem Bitmap macht.



Was man machen kann, das Bitmap für die VCL blocken, wenn es z.B. in einem TPicture steckt oder sonstwie angezeigt wird,
im Hauptthread sich den Anfang der Daten (ScanLine der letzen Zeile) besorgt und im thread nur "direkt" selber darin rummalt.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 9. Jan 2014 um 10:29 Uhr)
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#8

AW: Thread läuft nicht parallel --

  Alt 9. Jan 2014, 11:59
Mal abgesehen von der falschen Verwendung von Threads...

Das Kopieren eines Ausschnitts der ScreenBMP in die tempBmp ist hier der eigentlich bremsende Faktor.
Es erscheint mir sinnvoller die Funktion "Compare2Bitmaps" so anzupassen, dass statt zwei kompletter Bitmaps, nur der angegebene Bereich verglichen wird.

Compare2Bitmaps(80, SearchBMP, ScreenBMP, rectSource);
ich kopiere in die TempBmp einen Ausschnitt des Screens und nur der wird mit dem Suchbitmap verglichen. Verstehe jetzt nicht so ganz wie du es meinst.
Bin für Kritik und Verbesserung jederzeit zu haben ^^

Grüße s0n
Du versuchst die Geschwindigkeit zu verdoppeln in dem die Arbeit auf 2 Threads verteilt wird. Der eigentliche Zeitfresser ist aber das ständige Kopieren der ScreenBMP in die TempBMP. Wenn man dies vermeiden könnte, lies sich die Geschwindigkeit vermutlich vervielfachen, ohne mit Threads zu arbeiten. Dazu müsste halt lediglich die Funktion Compare2Bitmaps angepasst werden. Das sollte relativ einfach möglich sein, aber dafür bräuchte diese Funktion dann statt der TempBMP, die ScreenBMP und das Recheck für den Vergleich.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz