Einzelnen Beitrag anzeigen

Benutzerbild von Meflin
Meflin

Registriert seit: 21. Aug 2003
4.856 Beiträge
 
#1

Problem mit Multithreading in einer Klasse

  Alt 4. Jun 2005, 12:58
guten appetitAloha,

Ich bastel gerade an meiner ersten Klasse (jaja, tatsächlich ), 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?

  Mit Zitat antworten Zitat