Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Multi Threaded Application (https://www.delphipraxis.net/87969-multi-threaded-application.html)

Moony 8. Mär 2007 08:57


Multi Threaded Application
 
Hallo zusammen,

ich habe vor eine Multi Threaded Application bzw. DLL zu bauen und wollte fragen ob sich jemand damit auskennt & mir eventuell ein wenig Hilfestellung bezüglich Aufbau geben kann. Zumindest wäre es gut zu wissen wie solch ein Multithreading aufgebaut ist und funktioniert.

Danke schon mal im Vorraus.

Gruß, Moony

kaiser1401 8. Mär 2007 09:01

Re: Multi Threaded Application
 
Hallo,

auf die Schnelle würd ich dir empfehlen einfach mal da rein zu schauen:
http://www.dsdt.info/tutorials/threads/

yörsch 8. Mär 2007 09:50

Re: Multi Threaded Application
 
oder das Tutorial von Luckie

Pfoto 8. Mär 2007 10:59

Re: Multi Threaded Application
 
Hi!

wenn du das Multi-Threading mit einer Art Jobliste realisieren möchtest,
gibt es hier im Forum schon ein paar Themen.
Hier gibt es ganz unten ein kleines Beispiel. Das hatte mich auch weitergebracht.

Wenn du beliebige Aufträge in die Liste legen möchtest,
würde ich mich auch mit dem Thema Command-Pattern beschäftigen.
Jeden Befehl bettet man dann in eine TCommand-Klasse.

Wenn die Liste diesen Typ verarbeiten kann, kannst du ganz
auf die schnelle nahezu jeden beliebigen Befehl in diese
Liste tun.


Gruß
Pfoto

Moony 8. Mär 2007 17:09

Re: Multi Threaded Application
 
Danke für die zahlreichen Tips.

Ich habe es soweit hinbekommen, dass beim Initialisieren die benötigte Anzahl an Threads gestartet wird. Mir bleiben dann nur noch 2 Fragen:

1. Wie kann ich während der Laufzeit auf einen bestimmten Thread zugreifen?
2. Wie kann das Multitasking einsetzen. D.h. ich greife auf einen Thread zu. Während dieser ausgeführt wird, möchte ich auf einen anderen Thread zugreifen. Ist das möglich? Wenn ja, wie?

Mit meinem jetzigen Code geht das wohl nicht. Der andere Thread startet erst, wenn der eine beendet ist.

Pfoto 8. Mär 2007 18:42

Re: Multi Threaded Application
 
Zitat:

Zitat von Moony
1. Wie kann ich während der Laufzeit auf einen bestimmten Thread zugreifen?
2. Wie kann das Multitasking einsetzen. D.h. ich greife auf einen Thread zu. Während dieser ausgeführt wird, möchte ich auf einen anderen Thread zugreifen. Ist das möglich? Wenn ja, wie?

zu 1: Indem du entweder die deklarierte Instanz holst und dann darauf zugreifen
kannst oder, falls die Instanzen der Threads in einer Liste von Pointern liegen, könntest du
über die Listen-Einträge daran kommen.

zu 2: Wenn du das Beispiel aus meinem obigen Link nimmst, wo die Threads einfach
eine Jobliste abarbeiten und dann warten, bis es wieder was zu tun gibt, musst du im Prinzip
gar nicht mehr speziell auf einen Thread gezielt zugreifen. Du schiebst einach einen neuen
Job in die Liste und Threads arbeiten wieder brav.

Wenn du dem User erlauben möchstest, eine bestimmte Methode z.B. das Hochladen einer Datei
in einem eigens dafür eingerichteten Thread auszuführen, kannst du natürlich einen zweiten
Thread starten usw. Wenn du hier jedoch dem User die Möglichkeit lässt, beliebig viele Threads
zu starten, könnte das Dein Programm irgendwann in die Knie zwingen.

Deswegen "stehe" ich halt so auf die Jobliste... :)

Gruß
Pfoto

Moony 9. Mär 2007 08:55

Re: Multi Threaded Application
 
Ja, aber mit der Jobliste wird das nacheinander ausgeführt. Das ist ja nicht Sinn und Zweck meiner Übung.
Ich will einen Thread starten. Während dieser Thread ausgeführt wird, will ich einen anderen Thread starten. das soll also parallel erfolgen können.

Ich glaube ich habe eine Lösung gefunden. Mit dem Demoprojekt von Borland selbst. Indem Unterklassen von der Hauptklasse gebildet werden.

Ich meld mich wenn das geklappt hat.

Pfoto 9. Mär 2007 09:04

Re: Multi Threaded Application
 
Zitat:

Zitat von Moony
Ja, aber mit der Jobliste wird das nacheinander ausgeführt.

Das sehe ich anders - es kommt natürlich darauf an, wie viele Threads du erstellst, die an der Jobliste arbeiten - und dies geschieht dann auch parallel. Oder meinen wir Beide was anderes?

Gruß
Pfoto

Moony 14. Mär 2007 13:05

Re: Multi Threaded Application
 
ich werde es bei Gelegenheit versuchen, wenn die Zeit dafür da ist.

Jetzt mache ich das in meiner Applikation so wie das Demoprojekt von Borland mit den verschiedenen Sortiersystemen. Ich habe nur ein Problem, beim Beenden der Applikation kommt eine deftige Exception mit Runtime Error. Wie kann ich bei der Finalisierung sicherstellen, dass alle Threads ordnungsgemäß beendet werden?

ste_ett 14. Mär 2007 13:51

Re: Multi Threaded Application
 
Zitat:

Zitat von Moony
ich werde es bei Gelegenheit versuchen, wenn die Zeit dafür da ist.

Jetzt mache ich das in meiner Applikation so wie das Demoprojekt von Borland mit den verschiedenen Sortiersystemen. Ich habe nur ein Problem, beim Beenden der Applikation kommt eine deftige Exception mit Runtime Error. Wie kann ich bei der Finalisierung sicherstellen, dass alle Threads ordnungsgemäß beendet werden?

"MyThread.Free;" sollte reichen. :)

Moony 14. Mär 2007 14:29

Re: Multi Threaded Application
 
Das geht aber nicht in der Finalization....dort erkennt er nämlich die Klasse MyThread.Free nicht.

ste_ett 14. Mär 2007 14:43

Re: Multi Threaded Application
 
Wo hast du die Threads deklariert?
Global oder lokal?

Wenn sie global sind, sollten sie auch im Finalization-Teil verfügbar sein.

Moony 14. Mär 2007 14:59

Re: Multi Threaded Application
 
Wenn du mal im Borlandverzeichnis unter Demos in Threads schaust, dann sind meine Threads genauso deklariert wie bei borland, sprich:

Delphi-Quellcode:
type
  TMyThread = class(TThread)
  private
    { Private-Deklarationen }
    TFunc  : Byte;
    TData  : PChar;
    TNames : PChar;
    TValues : PChar;
    TIndex : Byte;
  protected
    procedure Execute; override;
    function Myfunction: Integer; virtual; abstract;
  public
    constructor Create(Func: Byte; Data, Names, Values: PChar; DriveIdx: Byte);
  end;

  TFirstThread = class(TMyThread)
  protected
    function Myfunction: Integer; override;
  end;

  TSecondThread = class(TMyThread)
  protected
    function Myfunction: Integer; override;
  end;
Unter Execute wird dann der jeweilige Thread aufgerufen und ausgeführt.

Moony 16. Mär 2007 09:53

Re: Multi Threaded Application
 
Hallo......weiß keiner eine Antwort???? :(

shmia 16. Mär 2007 10:55

Re: Multi Threaded Application
 
Zitat:

Zitat von Moony
Hallo......weiß keiner eine Antwort???? :(

Du hast doch schon gute Antworten bekommen.
Also, dein Programm darf erst dann beendet werden, wenn alle deine Thread beendet sind.
Wird das nicht beachtet, dann knallt's !!
Wenn du deine Thread-Objekte nicht in einer Jobliste sammelst, dann hast du später
keinen Zugriff auf deine Threadobjekte mehr und weisst nicht, ob dein Programm beendet werden darf.

So ein Thread kann ja auch recht lange laufen.
Deshalb muss der Thread immer wieder das Property Terminated abfragen, ob er eigentlich noch weiterlaufen darf:
Delphi-Quellcode:
procedure TMyThread.Execute;
var
   i : integer;
begin
   for :=1 to 1000000 do
   begin
      DoWork;
      if Terminated then  // <====
      begin
         ReturnValue := 9999; // signalisieren, dass wir unterbrochen wurden
         break;
      end;
   end;
   ReturnValue := 0; // Thread beendet, Aufgabe zu 100% erfüllt
end;
Hast du das beachtet ??

alzaimar 16. Mär 2007 11:28

Re: Multi Threaded Application
 
Du musst Dir angewöhnen, jedes instantiierte Objekt im korrespondierenden Kontext wieder freizugeben:
Hier ein paar Beispiele;

Delphi-Quellcode:
Procedure LokaleInstantiierung;
Var
  MyObject : TMyObject;

Begin
  MyObject := TMyObject.Create;
  Try
//    ... tu was mit MyObject
  Finally
    MyObject.Free;
  End;
End;
Delphi-Quellcode:
Unit GlobaleInstantiierung;
Interface...

implementation
Var
  MyObject : TMyObject;
...
Initialization
  MyObject := TMyObject.Create;
Finalization
  MyObject.Free;
End;
Delphi-Quellcode:
Type
  TClassField = Class (TBigObject)
    FMyObject : TMyObject;
  Public
    Constructor Create;
    Destructor Destroy;
  End;
...
Constructor TClassField .Create;
Begin
  ...
  FMyObject := TMyObject.Create;
End;

Destructor TClassField.Destroy;
Begin
  FMyObject.Free;
  Inherited
End;

Delphi-Quellcode:
Type
  TFormInstantiierung = Class (TForm)
...

    Procedure FormCreate (Sender : TObject);
    Procedure FormDestroy (Sender : TObject);
...
  Private
    FMyObject : TMyObject;
  End;

Procedure TFormInstantiierung.FormCreate (Sender : TObject);
Begin
  ...
  FMyObject := TMyObject.Create;
End;

Procedure TFormInstantiierung.FormDestroy (Sender : TObject);
Begin
  ...
  FMyObject.Free;
End;
Und vielleicht noch 'FreeAndNil' statt '.Free', das vermeidet böse Fehler.

Dann noch:

Einen Thread einfach so zu killen (mit Free / Destroy) ist natürlich tödlich. Richtig macht man es so:
Delphi-Quellcode:
With MyThread Do Begin
  Terminate; // Hör auf!
  WaitFor; // Warte bis er aufgehört hat!
  Free; // Jetzt erst resourcen freigeben (u.a. das Threadhandle ;-)
End;


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz