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/)
-   -   Delphi Problem mit Multithreading in einer Klasse (https://www.delphipraxis.net/46984-problem-mit-multithreading-einer-klasse.html)

Meflin 4. Jun 2005 11:58


Problem mit Multithreading in einer Klasse
 
guten appetitAloha,

Ich bastel gerade an meiner ersten Klasse (jaja, tatsächlich :stupid: ), und stoße dabei auf ein Problem beim Versuch aus dieser Klasse heraus Threads zu starten.

Erstmal der Code (unwichtiges ist weg):
Delphi-Quellcode:
unit BruteForce;

interface

uses Math, Classes, SyncObjs, SysUtils;

type TBruteForce = class(TObject)
  private
    fStrLen, fSubStrLen, fStartLength, fEndLength: Integer;
    fToDo, fProgres: Extended;
    fBatchSize, fMaxThreads: Integer;
    fChars, fSubString: string;
    fThreadHandles: array of THandle;
    fThreadIDs: array of Cardinal;
    function moc: extended;
    function ThreadFunction(): TStringList;
    function Dummie: Integer;
    procedure SetChars(str: string);
    procedure SetSubString(str: string);
    procedure SetStartLength(i: Integer);
    procedure SetEndLength(i: Integer);
    procedure SetBatchSize(i: Integer);
    procedure SetMaxThreads(i: Integer);
  public
    HeapControl: TCriticalSection;
    Heap: TStringList;
    procedure Start;
    procedure Stop;
    procedure Pause;
    property Chars: string read fChars write SetChars;
    property SubString: string read fSubString write SetSubString;
    property StartLength: Integer read fStartLength write SetStartLength;
    property EndLength: Integer read fEndLength write SetEndLength;
    property ToDo: Extended read fToDo;
    property Progres: Extended read fProgres;
    property BatchSize: Integer read fBatchSize write SetBatchSize;
    property MaxThreads: Integer read fMaxThreads write SetMaxThreads;
  end;

implementation

function TBruteForce.ThreadFunction(): TStringList;
var SubStr: string;
    i: Integer;

  procedure BruteForceFunc(const init, str: string);
  var i: integer;
      npw: string;
  begin
    if Result.Count >= fBatchSize then begin
      HeapControl.TryEnter;
      for i := 0 to Result.Count - 1 do
        Heap.Add(Result[i]);
      HeapControl.Leave;
      Result.Clear;
    end;

    for i := 1 to Length (str) do begin
      npw := init + str[i];
      if Length (npw) >= fStartLength then begin
        Result.Add(npw);
//        InterlockedExchangeAdd(@fProgres, 1);
        fProgres := fProgres + 1;
      end;
      if Length (npw) < fEndLength then BruteForceFunc (npw, str);
    end;
  end;

begin
  Result := TStringList.Create;

  if fStartLength = 1 then begin
    //Result.Add(SubStr);
    //fProgres := fProgres + 1;
  end;
//
//  BruteForceFunc (SubStr, fChars);
//
//  HeapControl.Enter;
//  for i := 0 to Result.Count - 1 do
//    Heap.Add(Result[i]);
//
//  HeapControl.Leave;
//  Result.Clear;
end;

procedure TBruteForce.Start;
var i: Integer;
begin
  fToDo := moc;

  HeapControl := TCriticalSection.Create;

  SetLength (fThreadHandles, fSubStrLen);
  SetLength (fThreadIDs, fSubStrLen);

  for i := 0 to fSubStrLen - 1 do begin
    fThreadHandles[i] := BeginThread(nil, 0, @TBruteForce.ThreadFunction, nil, 0, fThreadIDs[i]);
    //ThreadFunction(fSubString[i + 1]);
  end;
end;

end.
So. Wenn ich nun den Thread starte (die Threadfunction ist wie ihr sehen könnt fast komplett auskommentiert) wird eine Access Violation Exception bei dieser if Abfrage erzeugt. Scheint also als hätte ich da keinen Zugriff darauf.

Gibt es da auch noch eine andere Möglichkeit, als alle diese Variablen dem Thread zu übergeben, oder wo liegt der Fehler?


Luckie 4. Jun 2005 12:05

Re: Problem mit Multithreading in einer Klasse
 
Das Problem:
TThreadFunction ist so dekalriert:
Delphi-Quellcode:
function (p: Pointer): Integer;
Bei dir ist es eine Methode deiner Klasse. Somit stimmt die Parameterliste nicht mehr, da der unsichtbare self-Parameter noch dazu kommt.

Wie man Parameter an Threads übergibt und wie man generell mit ihnen Arbeitet, kannst du in meinem Tutorial: http://tutorials.luckie-online.de nachlesen.

SirThornberry 4. Jun 2005 12:05

Re: Problem mit Multithreading in einer Klasse
 
Ähm: "@TBruteForce.ThreadFunction" stimmt von den Parametern aber nicht wirklich mit den Parametern überein die erforderlich sind. Der dritte Parameter muss eine TthreadFunc sein die wie folgt definiert ist:
Delphi-Quellcode:
type TThreadFunc = function(Parameter: Pointer): Integer;
also muss deine Funktion als erstes einen parameter vom Typ Pointer bekommen und zweitens darf es keine Methode sein.

Wenn du die Objectorientierung wahren willst kannst du auch eine ThreadKlasse erstellen und von TThead ableiten. Im Demos verzeichnis von Delphi ist auch ein Beispiel dazu (die Methode Execute überschreiben und darin deinen Thread-Source auführen)

Meflin 4. Jun 2005 12:13

Re: Problem mit Multithreading in einer Klasse
 
Zitat:

Zitat von SirThornberry
also muss deine Funktion als erstes einen parameter vom Typ Pointer bekommen und zweitens darf es keine Methode sein.

Hm, also darna allein kann das nicht liegen. wenn ich mit
Delphi-Quellcode:
function TBruteForce.Dummie;
begin
  result := 0;
end;
der Dummie-Funktion anstelle der ThreadFunction den Thread starte, dann passiert da nichts, also auch keine access violation...

@Luckie: ich will ja eben nach Möglichkeit die Parameter nciht an den Thread übergeben...


SirThornberry 4. Jun 2005 12:16

Re: Problem mit Multithreading in einer Klasse
 
@melfin: Hast du mal debuggt ob in die Funktion hinein gesprungen wird? Desweiteren ist es schon wieder eine Methode!!!!

Luckie 4. Jun 2005 12:20

Re: Problem mit Multithreading in einer Klasse
 
Zitat:

Zitat von Meflin
@Luckie: ich will ja eben nach Möglichkeit die Parameter nciht an den Thread übergeben...

Ja was willst denn dann machen? Mit was soll denn der Thread arbeiten? Mit globalen Variablen?

Meflin 4. Jun 2005 12:34

Re: Problem mit Multithreading in einer Klasse
 
Zitat:

Zitat von SirThornberry
@melfin: Hast du mal debuggt ob in die Funktion hinein gesprungen wird? Desweiteren ist es schon wieder eine Methode!!!!

was ich damit sagen wollte, es kann nicht daran liegen dass die Threadfunktion eine Methode ist. Denn mit der DummieFunktion gehts, und es wird auch in sie hineingesprungen!

@Luckie: ich bin auf der suche nach der einfachsten Möglichkeit, diese Variablen aus dem Thread heraus zu lesen.


Luckie 4. Jun 2005 12:39

Re: Problem mit Multithreading in einer Klasse
 
Nimm die Thread-Funktion doch mal testweise aus deiner Klasse raus, dann wissen wir ja, ob es daran liegt.

Meflin 4. Jun 2005 17:12

Re: Problem mit Multithreading in einer Klasse
 
Zitat:

Zitat von Luckie
Nimm die Thread-Funktion doch mal testweise aus deiner Klasse raus, dann wissen wir ja, ob es daran liegt.

Das kann ich zwar machen, aber dann sind ja die ganzen Variablen aus der Klasse in der Funktion nicht mehr gültig. Kommentiere ich also den Code aus, dann läuft zwar der Thread, was mir aber nichts bringt, da ich dann die Variablen nicht im Thread habe.

Wies aussieht führt also kein Weg daran vorbei, die Variablen dem Thread zu übergeben, was zwar irgendwie blöd, weil doppeltgemoppelt ist, aber es geht wohl nicht anders :?


SirThornberry 4. Jun 2005 17:16

Re: Problem mit Multithreading in einer Klasse
 
mit der Dummyfunktion gehts weil diese den versteckten Self-Parameter hat welcher ein Pointer ist. würdest du jedoch in der Dummyfunktion auf self zugreifen und damit was machen sollte es auch krachen.

Deswegen auch die AV wenn du in der Klasse auf "HeapControl" zugreifst, weil in diesem Fall intern auf Self.HeapControl zugegriffen wird aber Self ist eben nicht die Klasseninstanz sondern der Pointer von BeginThread.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:09 Uhr.
Seite 1 von 2  1 2      

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