![]() |
Multithreading
Hallo liebe DP'ler
ich bin dabei eine ältere Anwendung von mir, auf die neuen Multicore CPU's umzuschreiben. Da ich aber noch nichts mit Thread zu tun hatte brauche ich etwas Hilfe. Die besagte Anwendung generiert Daten und trägt diese dann in Datenbank ein. Jetzt habe ich angefangen mit der Klasse TThread. Wie in einem Tutorial beschrieben hab ich die Klasse abgeleitet und die Methode Execute überschrieben. Das ganze sieht dann so aus:
Delphi-Quellcode:
aufgerufen hab ich es dann wie folgt:
type
meinThread = class(TThread) protected procedure Execute; override; end;
Delphi-Quellcode:
Nun hab ich mehrere Fragen zu der Geschichte:
procedure bla();
var t1 : meinThread; begin t1:=meinThread.Create(True); try t1.Execute; finally t1.Free; end; end; Wie kann ich es realisieren mehrere Threads parallel laufen zu lassen? Ist es sinnvoll die Threadanzahl der Anzahl an CPU's anzupassen? Sollte ich in jedem Thread eine eigene Datenbankverbindung anlegen oder die eine auf der Mainform nutzen? Ich danke allen Helfern schon mal im Voraus. MfG Prelude247 Für den Fall das es eine Rolle spielt, ich benutze die ZEOSlib und MySQL 5. |
Re: Multithreading
Dein Code...
Delphi-Quellcode:
...ist sinnlos. Überlege doch nochmal für was Threads überhaupt da sind - Richtig, um bestimmte Aufgaben parallel zur Hauptanwendung auszuführen. Was macht dein Code? Er startet einen Thread, der parallel zur Anwendung läuft. Nach dem Execute läuft also direkt deine Anwendung weiter und versucht den Thread freizugeben. Hierbei wird auf das Ende des Threads gewartet. Parallelität erreichst du so nicht. Und im schlimmsten Fall wird der Threadcontext freigegeben während er noch läuft. Das ist dann lustig.
try
t1.Execute; finally t1.Free; end; |
Re: Multithreading
Danke für die rasendschnelle Antwort.
Ok, das mit dem freigeben ist wahrscheinlich Bödsinn (zumindest an dieser Stelle). Jetzt habe ich aber versucht 4 von den Dingern laufen zulassen:
Delphi-Quellcode:
Aber die laufen nicht parallel, sondern werden nacheinander ausgeführt.
var
t1,t2,t3,t4 : meinThread; begin t1:=meinThread.Create(True); t2:=meinThread.Create(True); t3:=meinThread.Create(True); t4:=meinThread.Create(True); t1.Execute; t2.Execute; t3.Execute; t4.Execute; end; Was mache ich da falsch? Kann man das Erzeugen der Threads auch in einer Schleife machen? |
Re: Multithreading
Zitat:
es passiert also kein "Freigeben während er noch läuft". Du musste den Thread mit Resume starten. Dann wird automatisch die Execute-Prozedur (in einem eigenen Thread) ausgeführt. Du solltest dabei beachten, dass dann natürlich der Thread nicht direkt freigegeben werden darf und das die Execute-Prozedur auch irgendwann fertig wird. Für das erste Problem setze FreeOnTerminate auf True... |
Re: Multithreading
Zitat:
Erst als ich in meinem Code noch ein "WaitFor" und ein "Terminate" eingeschoben hatte lief es ohne Probleme:
Delphi-Quellcode:
for i := 0 to High(Threads) do
begin Threads[i].Terminate; Threads[i].WaitFor; FreeAndNil(Threads[i]); end; |
Re: Multithreading
Eine Datenbankanbindung pro Thread. Das geht aber nur, wenn es dein Konzept erlaubt, dass auch Datenbanksachen gleiczeitig laufen können. Ansonsten geht eben nur ein Datenbankthread.
Der Parameter im constructor gibt an, ob der Thread gleich loslaufen soll (False) oder noch auf ein Resume warten soll (True). Und niemals Execute direkt aufrufen. Die Methode steht ja auch unter protected (und gehört besser unter strict protected). |
Re: Multithreading
Hier mal ein kleines Beispiel:
(Benötigt 1 Formular mit einer TMemo und einer TButton-Komponente. Das "Button1Click" - Event gehört zu Button1: TButton;. Die Procedure "ThreadTerminated" musst du selbst in der Form deklarieren.
Delphi-Quellcode:
(Code ungetestet, da der ohne Delphi geschrieben wurde)
type
TMyThread = class(TThread) protected Counter : integer; // nur für die Ausgabe procedure Execute; override; end; procedure TMyThread.Execute; begin // Der Thread soll einfach nur warten. Dabei wartet er // zufällig zwischen 1 und 11 Sekunden Sleep(1000 + random(10001)); end; procedure TForm1.Button1Click(Sender: TObject); var i: integer; begin for i:=1 to 6 do begin Memo1.Lines.Add('Erstelle Thread Nummer '+IntToStr(i)); with TMyThread.Create(True) do begin Counter := i; FreeOnTerminate := True; OnTerminate := ThreadTerminated; Resume; end; end; end; procedure TForm1.ThreadTerminated(Sender: TObject); begin if Sender is TMyThread then begin Memo1.Lines.Add('Der Thread '+IntToStr(TMyThread(Sender).Counter)+' ist fertig'); end; end; Bei dem Beispiel wirst du merken, dass das Programm trotz Sleep noch normal weiterläuft: es wird nur der Thread angehalten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:47 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 by Thomas Breitkreuz