Nein, ievent erbt von iobjectlink welches solche Dinge regelt.mschnell hat geschrieben:War da die Rede von ? Das Problem tritt doch bei tcomponentevent auch auf. Oder nicht ?
wie shared man daten zwischen main und subthreads? [gelöst]
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: wie shared man korrekt daten zwischen main und subthread
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: wie shared man korrekt daten zwischen main und subthread
Super.
-Michael
-Michael
Re: wie shared man korrekt daten zwischen main und subthread
Bitte MSEGUI Probleme im entsprechenden Forum behandeln. Danke!
Es ist nicht hilfreich, hier die Klassenbibliotheken zu vermischen.
http://www.msegui.org/?q=node/10
http://www.lazarusforum.de/viewforum.php?f=53
Es ist nicht hilfreich, hier die Klassenbibliotheken zu vermischen.
http://www.msegui.org/?q=node/10
http://www.lazarusforum.de/viewforum.php?f=53
Re: wie shared man korrekt daten zwischen main und subthread
Hui danke aber ich kann / muss / möchte Euch mal ausbremsen. Ich hab in dem Beispiel alles gesehen / erklärt bekommen, was ich für mein Projekt brauche. Ich hab eigentlich fast keine offenen Fragen mehr. Das Problem in meinem alten Aufbau war nicht unbedingt die Datenübergabe, ich habe anstatt einen Thread zu starten und den dann laufen zu lassen immer wieder neu Create/Free gemacht und das mit 10 Threads im Laufe von einigen Tagen Millionen mal.Eine andere Möglichkeit ist ein globaler lock im main-thread
Der ganze Aufbau, was ich wie, wo gemacht habe usw. war ungünstig und vollkommen anders als man es normalerweise macht. Ich hab jetzt mein Execute leer gemacht und baue Stück für Stück alles ordentlich sauber und vernünftig wieder zusammen. Vorher globale Variablen sind nun lokal im Thread, musste zwar viel drum rum ändern aber hier will ich / sollte man keine Kompromisse eingehen. Dabei achte ich primär darauf was am Besten wo und wann berechnet werden muss und wie/wo/wann ich auf Daten zugreife, bestimmte Dinge sollen die WorkerThreads tun, bestimmte Dinge soll der MainThread tun.
Ich hab ca. 50% schon wieder drin und das was ich sehe, sieht schon ganz anders aus und läuft wesentlich besser als zuvor. Ich gehe davon aus, das meine Access Violation irgendwo in meinem zusammengewürfelten Aufbau entstand. Wenn ich aus einem WT auf Speicherbereiche des MT zugreifen muss (was ich so selten wie möglich und nur kurz tue) dann über Synchronise oder ich werde CriticalSections einsetzen.
Ok, angenommen Du willst Daten berechnen und diese auf nen Chart zeichen.Erklär' doch mal, was Du mit "synchronisiere" meinst ?
Code: Alles auswählen
procedure TEvoThread.SyncCalcAndDraw; // da die komplette Funktion synchronisiert wurde, führt der MainThread die Berechnungen durch oder nicht?
begin
rechne...............
rechne...............
rechne...............
rechne...............
Form1.DrawOnChart();
end;
procedure TEvoThread.WorkerCalc; // da die Funktion im WT ohne Synchronize aufgerufen wird, führt der WorkerThread die Berechnungen durch oder nicht?
begin
rechne...............
rechne...............
rechne...............
rechne...............
Synchronize(@SyncDraw); // der MainThread muss hier nur zeichnen
end;
procedure TEvoThread.SyncDraw;
begin
Form1.DrawOnChart(); // der MainThread muss hier nur zeichnen
end;
procedure TEvoThread.Execute;
begin
while not(Terminated) do begin
Synchronize(@SyncCalcAndDraw); // da die komplette Funktion synchronisiert wird, führt der Mainthread die Berechnungen durch oder nicht?
--- oder ----
WorkerCalc(); // da die Funktion im WT aufgerufen wird, führt der WorkerThread die Berechnungen durch oder nicht?
end;
end;

Lieber Theo, Du hast mir wie viele hier schon viel gegeben ohne dafür etwas zu verlangen. Dafür bin ich Dir sehr dankbar. Und nein, so richtig pampig war das nichtWarum wirst du jetzt pampig? Du hast mich gefragt:

Ich finde nur 2 Dinge nicht gut:
1. Wenn jemand ohne das komplette Thema zu kennen eine Meinung hat.
2. Wenn mir jemand sagt, ich soll etwas lassen, nur weil ich es (jetzt) noch nicht kann.
Ich zähle mich selbst und sicher auch alle hier zu der Gruppe Menschen die aus Ihren Fehlern lernen, sonst könnte man nie wirklich programmieren. Aber es gibt immer wieder so Leute die wollen einem Projekte ausreden oder sind aufgrund eigener Erfahrungen geprägt. Das kannst Du nicht gibt es bei mir nicht, wenn ich etwas will setze ich mich solange davor hin bis ich es hab, ohne Kompromisse. Und Du kannst mir glauben, ich gehe da wesentlich weiter als die meisten Menschen.
Das tut mir wirklich leid, ich hatte nur gefragt ob man das genauso ohne Threads machen könnte, ich wollte / wusste nicht das Du Dir extra die Arbeit machst und es umsetzt. Sorry wirklich!Dann habe ich mir die Mühe gemacht, dir ein Programm zu schreiben, welches genau das zeigt.

Richtig, absolut! Genau wegen dem fehlenden Durchblick bin ich ja in einem Forum und stelle so verdrehte Fragen und verstehe manchmal Eure Antworten nicht sofort. Also frage ich solange weiter bis es KLICK macht und dann fällt mir meist auf wie bescheuert ich wieder war. Aufgrund fehlender Grundlagen bau ich mir gern eigene Konstrukte die Ihr dann logischerweise falsch versteht oder ich stelle Fragen unklar weil mir eine Info fehlt. (Ich brauch meinen eigenen DisclaimerUnd außerdem habe ich bei dir den Eindruck, dass du einfach was kompliziertes haben möchtest, aber nicht so ganz den Durchblick hast.

Nimm mal bitte das Beispiel vom Michl, lösch mal den Sleep im WorkerThread und setz den Timer auf 10ms. Wenn Du dann (so wars bei mir) alle Threads aktivierst und versuchst mal zu zoomen + den Chart zu bewegen, solltest Du sehen wie das ruckelt.In deinem letzten Code, machst du das ganze Thread Brimborium um nach jedem Durchlauf 10ms zu sleepen?
Durch den kleinen Sleep im WorkerThread bleiben mehr Rechenzyklen für den MainThread übrig und das Ruckeln verschwindet.
Das habe ich mir ausnahmsweise nicht einfach mal wieder so ausgedacht, das steht auch hier unter Prioritäten : http://wiki.delphigl.com/index.php/Tuto ... ithreading
Code: Alles auswählen
while (not Terminated) do begin
if (BerechnungDa) then begin
// berechne
end;
end;
// An und für sich wäre das ja schon die Lösung des Problems. Allerdings dadurch, dass ich permanent nachschaue ob ich eine Berechnung da habe, würde dieser Thread so viel an CPU klauen, dass für die anderen nichts mehr übrig bliebe. Wenn ich die Priorität auf Echtzeit gesetzt habe kann es sogar sein, dass Windows stehen bleibt und sich nur noch auf das konzentriert. Eine Lösung für dieses Problem wäre wenn ich nur ein paar mal in der Sekunde nachschauen würde:
while (not Terminated) do begin
if (BerechnungDa) then begin
// berechne
end else begin
sleep(10);
end;
end;
Ahh Sarkasmus liegt Dir mehr, verstehe lachAber das war jetzt bestimmt auch gar nicht so gemeint sondern nur ein Beispiel...

Re: wie shared man korrekt daten zwischen main und subthread
Ach, den hatte ich ja gestern gar nicht mehr gesehen. Das kann ich nicht unkommentiert lassen.
Dann wirst du aber nicht mehr viele Antworten erhalten.
Zu 2. Falsch interpretiert. Ich glaube schon, dass du es programmieren kannst, ich glaube eher, dass du nicht einschätzen kannst was sinnvoll ist.
Und jetzt willst du irgendwas beweisen im Sinne von "Jetzt erst recht".
Ich wollte dir nur einen Tipp geben. Mir ist letztlich eigentlich egal was du machst.
Ich persönlich verwende Multi-Threading nur, wenn es nicht anders geht.
Warum sollte ich ohne Not
- Die Komplexität erhöhen?
- Neue Fehlerkategorien ermöglichen?
- Das Debugging erschweren?

Zu 1. OK, man darf also keine Meinung haben, wenn man nicht dein ganzes Thema in allen Einzelheiten kennt?laz847 hat geschrieben: Ich finde nur 2 Dinge nicht gut:
1. Wenn jemand ohne das komplette Thema zu kennen eine Meinung hat.
2. Wenn mir jemand sagt, ich soll etwas lassen, nur weil ich es (jetzt) noch nicht kann.
Dann wirst du aber nicht mehr viele Antworten erhalten.
Zu 2. Falsch interpretiert. Ich glaube schon, dass du es programmieren kannst, ich glaube eher, dass du nicht einschätzen kannst was sinnvoll ist.
Ich will dir nichts ausreden. Ich glaube du hast einfach nicht so gut verdaut, dass dein Beispiel ohne Multi-Threading besser funktioniert.laz847 hat geschrieben: Aber es gibt immer wieder so Leute die wollen einem Projekte ausreden oder sind aufgrund eigener Erfahrungen geprägt. Das kannst Du nicht gibt es bei mir nicht, wenn ich etwas will setze ich mich solange davor hin bis ich es hab, ohne Kompromisse.

Und jetzt willst du irgendwas beweisen im Sinne von "Jetzt erst recht".
Ich wollte dir nur einen Tipp geben. Mir ist letztlich eigentlich egal was du machst.
Ich persönlich verwende Multi-Threading nur, wenn es nicht anders geht.
Warum sollte ich ohne Not
- Die Komplexität erhöhen?
- Neue Fehlerkategorien ermöglichen?
- Das Debugging erschweren?
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: wie shared man korrekt daten zwischen main und subthread
Ich hielte es für sehr sinnvoll einen Event-Mechanismus für die LCL zu bauen, bei dem man Objekte von einer Standard-Klasse ableiten kann, die die besagte "closure"-Event Prozedur enthält und dann an TThread.Queue übergibt.theo hat geschrieben:Es ist nicht hilfreich, hier die Klassenbibliotheken zu vermischen.
Dabei kann es natürlich durchaus Sinn machen, den von MSE vorgebrachten Einwand zu berücksichtigen.
-Michael
Re: wie shared man korrekt daten zwischen main und subthread
Mag sein, aber erstens ist dieser Thread nicht der Ort, um solche Pläne zu besprechen und zweitens möchte ich darum bitten, MSEGUI Klassen im entsprechenden Unterforum zu behandeln. http://www.lazarusforum.de/viewforum.php?f=53mschnell hat geschrieben:Ich hielte es für sehr sinnvoll einen Event-Mechanismus für die LCL zu bauen, bei dem man Objekte von einer Standard-Klasse ableiten kann, die die besagte "closure"-Event Prozedur enthält und dann an TThread.Queue übergibt.theo hat geschrieben:Es ist nicht hilfreich, hier die Klassenbibliotheken zu vermischen.
Dabei kann es natürlich durchaus Sinn machen, den von MSE vorgebrachten Einwand zu berücksichtigen.
Diese führen im Lazarus Teil dieses Forums nur zu Verwirrung.
Danke.
Re: wie shared man korrekt daten zwischen main und subthread
Wirf doch nich immer wieder den Handschuh hin
... Hihi, Theo ick mag da
Wir beiden könnten bestimmt stundenlang quatschen lach
.
, an alle anderen OFFTOPIC

Und nun sage ich es zum 3 Mal, in diesem Beispiel benötigt man nicht zwingend Threads um die 7 Kurven anzuzeigen. Von daher hast Du mit dieser Aussage Recht, was Du dann auch noch bewiesen hast.
Trotzdem möchte ich meinem Projekt Threads verwenden, die Berechnungen in meinem Projekt sind wesentlich aufwendiger als 7 Sinuskurven und ich benötige eine gleichzeitige Berechnung der 10 verschiedenen Inputs. Natürlich nutze ich die Threads auch, um auf 4 anstatt nur 1 CPU-Kern zu rechnen.
Simples Beispiel, wie Du ja evtl. bemerkt hast, hat mein Projekt mit der Börse zu tun. Einen sogenannten Backtest bzw. eine Optimierung macht man, in dem allen möglichen Variationen von Einstellungen auf Datenreihen durchprobiert (vergleichbar brute-force). Spätestens ab diesem Punkt muss jedem klar sein, das 4 CPU-Kerne so etwas schneller können als 1 CPU-Kern. Nutze ich keine Threads, nutze ich erstmal nur 1 Kern oder? + Faktor Rechenlast + Faktor gleichzeitig
Hamwas
?
Liebe Grüße



Ich auch nichtDas kann ich nicht unkommentiert lassen.


Ich würde da jetzt erstmal den Begriff Meinung definieren. Viele Menschen denken sie haben zu etwas / von etwas eine MEINUNG, belegt man Ihnen dann aber mit DATEN, FAKTEN, WISSEN das Ihre Meinung nur auf Halb - bzw. gar keinem Wissen zum Thema beruht, wird oft klar, dass Ihre Meinung nur Vorurteile waren. Ich denke bzw. handhabe es so, dass ich mir eine Meinung erst bilde, wenn ich mich umfassend mit dem Thema befasst habe. Zu oft dachte ich eine Meinung zu haben um dann festzustellen, dass ich in Wahrheit einfach nur keine Ahnung hatte. Wenn ich von einem Thema keine Ahnung hab, frage ich, sag nix und höre erstmal zu. Wie Du oder andere das handhaben ist mir egal, ich mach es so und fahr gut damit.man darf also keine Meinung haben, wenn man nicht dein ganzes Thema in allen Einzelheiten kennt?

Wenn nicht ich als "Erschaffer" dieses Projekts, wer dann? Nach meiner Definition kannst Du zu meinem Projekt keine "Meinung" haben, Du kennst < 2 % Quellcode. Du weißt überhaupt nicht was ich wie, wo, wann, warum, wie oft, wie lange mache, legst aber einfach mal fest, dass geht genauso ohne Threads. Wenn Du Dir aufgrund von so wenigen Infos eine Meinung bilden kannst - bitte - mach es so.Ich glaube schon, dass du es programmieren kannst, ich glaube eher, dass du nicht einschätzen kannst was sinnvoll ist.
Ich kanns nur nochmal sagen, wir reden hier von 2 verschiedenen Dingen. Das hier im Thema angefragte Beispiel, also 7 Threads berechnen etwas und zeichnen im Chart, diente nur dazu, mir mal den richtigen Ablauf zu zeigen. Dazu reichte mir ein ganz simples Beispiel, ich habe nur ganz simple und vereinfacht nachgefragt und dafür ein super Beispiel bekommen wie man es machen kann / macht. Durch den Quellcode in diesem Beispiel habe ich bemerkt, dass ich in meinem Projekt die Threads blöd / falsch implementiert habe.Ich glaube du hast einfach nicht so gut verdaut, dass dein Beispiel ohne Multi-Threading besser funktioniert.
Und nun sage ich es zum 3 Mal, in diesem Beispiel benötigt man nicht zwingend Threads um die 7 Kurven anzuzeigen. Von daher hast Du mit dieser Aussage Recht, was Du dann auch noch bewiesen hast.
Trotzdem möchte ich meinem Projekt Threads verwenden, die Berechnungen in meinem Projekt sind wesentlich aufwendiger als 7 Sinuskurven und ich benötige eine gleichzeitige Berechnung der 10 verschiedenen Inputs. Natürlich nutze ich die Threads auch, um auf 4 anstatt nur 1 CPU-Kern zu rechnen.
Simples Beispiel, wie Du ja evtl. bemerkt hast, hat mein Projekt mit der Börse zu tun. Einen sogenannten Backtest bzw. eine Optimierung macht man, in dem allen möglichen Variationen von Einstellungen auf Datenreihen durchprobiert (vergleichbar brute-force). Spätestens ab diesem Punkt muss jedem klar sein, das 4 CPU-Kerne so etwas schneller können als 1 CPU-Kern. Nutze ich keine Threads, nutze ich erstmal nur 1 Kern oder? + Faktor Rechenlast + Faktor gleichzeitig
Hamwas

Liebe Grüße

Zuletzt geändert von laz847 am Do 2. Apr 2015, 22:53, insgesamt 1-mal geändert.
Re: wie shared man korrekt daten zwischen main und subthread
Ja, ich glaub ich hab's.laz847 hat geschrieben: Hamwas ?
Du weißt alles besser und dann weißt du doch wieder nichts.
Das ist mir zu anstrengend.
Re: wie shared man korrekt daten zwischen main und subthread
Ja diese Art Reaktion kenne ich - Eingeschnappte Leberwurst 
--------------------------------------------------------------------------------------------------------------------------------
Zurück zum Thema, ich habe oben einen Quelltext gepostet und gestern im Bett fiel mir ein. Moment mal, wasn das fürn Murks, da stimmt was nicht.
TEvoThread.SyncCalcAndDraw; vs. Form1.SyncCalcAndDraw;
Wofür und wann man Synchronize benötigt ist klar aber gibts da evtl. etwas zu beachten wenn man über Synchronize() Routinen vom TEvoThread oder Form1 aufruft?

--------------------------------------------------------------------------------------------------------------------------------
Zurück zum Thema, ich habe oben einen Quelltext gepostet und gestern im Bett fiel mir ein. Moment mal, wasn das fürn Murks, da stimmt was nicht.
Code: Alles auswählen
procedure TEvoThread.SyncCalcAndDraw; // da die komplette Funktion synchronisiert wurde, führt der MainThread die Berechnungen durch oder nicht?
begin
rechne...............
rechne...............
rechne...............
rechne...............
Form1.DrawOnChart();
end;
Synchronize(@SyncCalcAndDraw); // da die komplette Funktion synchronisiert wird, führt der Mainthread die Berechnungen durch oder nicht?
Wofür und wann man Synchronize benötigt ist klar aber gibts da evtl. etwas zu beachten wenn man über Synchronize() Routinen vom TEvoThread oder Form1 aufruft?