![]() |
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:
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.
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. Gibt es da auch noch eine andere Möglichkeit, als alle diese Variablen dem Thread zu übergeben, oder wo liegt der Fehler? |
Re: Problem mit Multithreading in einer Klasse
Das Problem:
TThreadFunction ist so dekalriert:
Delphi-Quellcode:
Bei dir ist es eine Methode deiner Klasse. Somit stimmt die Parameterliste nicht mehr, da der unsichtbare self-Parameter noch dazu kommt.
function (p: Pointer): Integer;
Wie man Parameter an Threads übergibt und wie man generell mit ihnen Arbeitet, kannst du in meinem Tutorial: ![]() |
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:
also muss deine Funktion als erstes einen parameter vom Typ Pointer bekommen und zweitens darf es keine Methode sein.
type TThreadFunc = function(Parameter: Pointer): Integer;
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) |
Re: Problem mit Multithreading in einer Klasse
Zitat:
Delphi-Quellcode:
der Dummie-Funktion anstelle der ThreadFunction den Thread starte, dann passiert da nichts, also auch keine access violation...
function TBruteForce.Dummie;
begin result := 0; end; @Luckie: ich will ja eben nach Möglichkeit die Parameter nciht an den Thread übergeben... |
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!!!!
|
Re: Problem mit Multithreading in einer Klasse
Zitat:
|
Re: Problem mit Multithreading in einer Klasse
Zitat:
@Luckie: ich bin auf der suche nach der einfachsten Möglichkeit, diese Variablen aus dem Thread heraus zu lesen. |
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.
|
Re: Problem mit Multithreading in einer Klasse
Zitat:
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 :? |
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. |
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