Autor Beitrag
hui1991
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Do 18.12.08 18:31 
Hallo,

ich hab mich mit Parallelisierung ein wenig befasst. Hab jetzt ein Demo Programm das eine Funktion auf 4 Kerne aufteilt.
Jetzt hab ich mir gedacht, ich tuhe das in einer eigenen Unit und einer eigenen Klasse reinpacken.
Blos ich bekomme ich ThreadFunc in meiner Klasse nicht gestartet, weil die Funktion keine Variable mehr ist.
Die Suche hat nichts gebracht, nur Müll in der Suche gekommen.

So sieht mein Code aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type
  TQuadThreadingExampleClass = class
  private
    LocalVariables: TExampleWorking;
    function Thread1:Integer;
    function Thread2:Integer;
    function Thread3:Integer;
    function Thread4:Integer;
    function ThreadFunc(tp: PQuadThreadingExampleInformation): Integer;
  public
    procedure Run;
  published

  end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function TQuadThreadingExampleClass.ThreadFunc(tp: PQuadThreadingExampleInformation): Integer;
var
  Number: Integer;
begin
  Number := PQuadThreadingExampleInformation(tp)^.Number;

  if Number = 1 then begin
    Thread1;
  end;
  if Number = 2 then begin
    Thread2;
  end;
  if Number = 3 then begin
    Thread3;
  end;
  if Number = 4 then begin
    Thread4;
  end;
  result := 0;    
end;




Aufrufen tuhe ich jetzt ThreadFunc so:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
procedure TQuadThreadingExampleClass.Run;
var
  tp1, tp2, tp3, tp4: PQuadThreadingExampleInformation;
  Thread1, Thread2, Thread3, Thread4: THandle;
  ThreadID1, ThreadID2, ThreadID3, ThreadID4: Cardinal;
begin
  // Speicher für Struktur reservieren.
    New(tp1);
    New(tp2);
    New(tp3);
    New(tp4);

  // Daten den feldern der Struktur zuweisen.
    tp1.Number := 1;
    tp2.Number := 2;
    tp3.Number := 3;
    tp4.Number := 4;

  // Thread 1 erzeugen.
    Thread1 := BeginThread(nil0@ThreadFunc, tp1, 0, ThreadID1);

  // Thread 2 erzeugen.
    Thread2 := BeginThread(nil0@ThreadFunc, tp2, 0, ThreadID2);

  // Thread 3 erzeugen.
    Thread3 := BeginThread(nil0@ThreadFunc, tp3, 0, ThreadID3);

  // Thread 4 erzeugen.
    Thread4 := BeginThread(nil0@ThreadFunc, tp4, 0, ThreadID4);

  // Auf Beendigung der Threads warten.
    WaitForSingleObject(Thread1, INFINITE);
    WaitForSingleObject(Thread2, INFINITE);
    WaitForSingleObject(Thread3, INFINITE);
    WaitForSingleObject(Thread4, INFINITE);

    Dispose(tp1);
    Dispose(tp2);
    Dispose(tp3);
    Dispose(tp4);
end;


Das Problem ist, das er die makierte Stelle nicht akzeptiert.
Wenn ich die ThreadFunc Funktion so ändere:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function [s]TQuadThreadingExampleClass.[/s]ThreadFunc(tp: PQuadThreadingExampleInformation): Integer;
var
  Number: Integer;
begin
  Number := PQuadThreadingExampleInformation(tp)^.Number;

  if Number = 1 then begin
    Thread1;
  end;
  if Number = 2 then begin
    Thread2;
  end;
  if Number = 3 then begin
    Thread3;
  end;
  if Number = 4 then begin
    Thread4;
  end;
  result := 0;    
end;


Akzeptiert er zwar die Zeile, kann aber Thread1,Thread2,Thread3 und Thread4 net aufrufen.

Gibt es eine Lösung das er es trotzdem schluckt?
So weit ich weiß, gibt es noch eine andere Möglichkeit Threads zu starten, aber diese Möglichkeit finde ich einfacher.

Danke schonmal im Vorraus.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 18.12.08 18:49 
Das Problem ist, dass sich die Funktionen Thread1, Thread2 usw. ja auf ein bestimmtes Objekt beziehen. Du könntest dieses z.B. in deine PQuadThreadingExampleInformation mit hineinschreiben und dann daraus die Funktionen aufrufen.

Direkt wird es auch gehen, das müsste ich nochmal anschauen.

user profile iconhui1991 hat folgendes geschrieben Zum zitierten Posting springen:
So weit ich weiß, gibt es noch eine andere Möglichkeit Threads zu starten, aber diese Möglichkeit finde ich einfacher.
Ich ganz und gar nicht, aber Hauptsache du findest es einfacher. :D
hui1991 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Do 18.12.08 19:12 
Naja ich brauch ja die Daten aus der Klasse in den einzelnen Threads.
Die PQuadThreadingExampleInformation dient ja nur dazu damit die ThreadFunc weiß, welche Procedure gestartet werden soll.
In der Procedur wird dann auf die Klasse TQuadThreadingExampleClass mehrfach zugegriffen.

Was ich machen könnte wäre ein Pointer von der Klasse übergeben.

also z. B. so
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  tp1.ClassPointer := @self;
    tp2.ClassPointer := @self;
    tp3.ClassPointer := @self;
    tp4.ClassPointer := @self;


Und das dann als Parameter übergeben.

Hab das dann direkt ausprobiert und funktioniert :D
Zumindest kommen keine AVs

Wenn es aber eine bessere Lösung gibt, dann würde ich mich darüber auch freuen. :)