Methode im ThreadContext ausführen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Bergmann89
Beiträge: 98
Registriert: Di 15. Nov 2011, 11:36

Methode im ThreadContext ausführen

Beitrag von Bergmann89 »

Hey Leute,

ich arbeite zur Zeit an einer Konsolenanwendung die aus mehreren Threads aufgebaut ist. Nun möchte ich bestimmte Methoden im Context eines bestimmten Threads ausführen. Wie mach ich das am dümmsten? Messages kommen nicht in Frage, da die Anwendung auch unter Linux laufen muss. Ich hab mir überlegt selbst sowas wie ne MessageQueue zu implementieren, die mit CriticalSections geschützt wird. Aber ich bin mir ziemlich sicher, da es dafür schon was vorgefertigted gibt. Ich weiß nur nicht wonach ich suchen soll :/

MfG & Thx Bergmann.

Benutzeravatar
theo
Beiträge: 11306
Registriert: Mo 11. Sep 2006, 19:01

Re: Methode im ThreadContext ausführen

Beitrag von theo »


Bergmann89
Beiträge: 98
Registriert: Di 15. Nov 2011, 11:36

Re: Methode im ThreadContext ausführen

Beitrag von Bergmann89 »

Hey,

die Sachen hab ich schon gefunden, aber die Lösen mein Problem nicht wirklich. Send- und PostMessage geht nur unter Windows. Und die Parallel Procedures sind auch nicht wirklich das was ich brauch. Der Thread läuft bei mir und führt Netzwerkabfragen aus. Wenn der User jetzt einige Einstellungen vornimmt, dann soll die jeweilige Prozedur im Context des schon laufenden Threads ausgeführt werden. Da gehen die Parallel Procedures nich wirklich...

Mfg Bergmann.

mse
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: Methode im ThreadContext ausführen

Beitrag von mse »

Bergmann89 hat geschrieben: Aber ich bin mir ziemlich sicher, da es dafür schon was vorgefertigted gibt. Ich weiß nur nicht wonach ich suchen soll :/
MSEgui hat dafür teventthread und tthreadcomp.
https://gitorious.org/mseide-msegui/mse ... thread.pas
https://gitorious.org/mseide-msegui/mse ... adcomp.pas
Zudem haben MSEgui Konsolenprogramme eine main event loop und können wie GUI-Programme ereignisgesteuert betrieben werden.

Martin

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Methode im ThreadContext ausführen

Beitrag von Scotty »

Bergmann89 hat geschrieben:Messages kommen nicht in Frage, da die Anwendung auch unter Linux laufen muss.
PostMessage() ist (plattformunabhängig) in der unit LCLIntf definiert. Und in LMessages sind die LCL-Pendants zu WMs definiert. Keine Ahnung, wie threadsicher das ist. Aber einen Timer mit Countdown, der in der GUI angezeigt wird, konnte ich damit aus Synchronize() heraus betreiben.

mschnell
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: Methode im ThreadContext ausführen

Beitrag von mschnell »

Bergmann89 hat geschrieben: Send- und PostMessage...
In einem grafischen Programm sollte PostMessage() gehen. Um eine Message an den Mainthread zu versenden ist aber QueueAsyncCall() besser (weil es nicht irgendwelche Windows-Artefakte in das User-Programm trägt).

In einer Konsol-Anwendung geht das alles nicht. In Lazarus gibt es bisher keinen "WidgetTyp" (siehe "Projekt-Potionen" -> "Build Mode"), der eine Message Queue bietet. TTimer geht deshalb auch nicht. (Finde ich auch ziemlich ärgerlich, ist aber nicht so leicht zu machen...)

Alternativ kannst Du auf Linux und Windows MSE-GUI und auf Windows Delphi verwenden. Die können das beide.

An Worker-Threads kannst Du sowieso keine Messages schicken (oder Asynchrone Calls anfordern), weil sie gar keine Message-Queue (also eine Instanz von TApplication) haben. (Finde ich auch ziemlich ärgerlich ist aber auch in MSEGUI und in Windows so.)

Du denkst vermutlich an etwas wie http://wiki.freepascal.org/OpenMP_support. Da ist aber wohl noch nichts verfügbar.
Für Deine Idee musst Du schon selbst Message-Queues programmieren.

-Michael
Zuletzt geändert von mschnell am So 14. Okt 2012, 22:52, insgesamt 4-mal geändert.

mschnell
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: Methode im ThreadContext ausführen

Beitrag von mschnell »

Scotty hat geschrieben:PostMessage() ist (plattformunabhängig) in der unit LCLIntf definiert. Und in LMessages sind die LCL-Pendants zu WMs definiert. Keine Ahnung, wie threadsicher das ist. Aber einen Timer mit Countdown, der in der GUI angezeigt wird, konnte ich damit aus Synchronize() heraus betreiben.
PostMessage ist schon Thread-sicher, sonst wäre es ja sinnlos. (Es kann aus beliebigen Threads Messages an den Mainthread schicken, aber nicht an "Worker"-Threads). (Wenn Du eine GUI hast ist es aber eben keine Konsolen-Anwendung !)

-Michael

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Methode im ThreadContext ausführen

Beitrag von Scotty »

mschnell hat geschrieben:Wenn Du eine GUI hast ist es aber eben keine Konsolen-Anwendung!
Schon klar. Aber warum sollte eine Konsolenanwendung nicht LCLInf benutzen dürfen?

mse
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: Methode im ThreadContext ausführen

Beitrag von mse »

mschnell hat geschrieben: An Worker-Threads kannst Du sowieso keine Messages schicken (oder Asynchrone Calls anfordern), weil sie gar keine Message-Queue (also eine Instanz von TApplication) haben. (Finde ich auch ziemlich ärgerlich ist aber auch in MSEGUI und in Windows so.)
MSEgui teventthread und tthreadcomp haben eine event (=message) queue.

mse
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: Methode im ThreadContext ausführen

Beitrag von mse »

Scotty hat geschrieben:
mschnell hat geschrieben:Wenn Du eine GUI hast ist es aber eben keine Konsolen-Anwendung!
Schon klar. Aber warum sollte eine Konsolenanwendung nicht LCLInf benutzen dürfen?
Weil der Server kein Qt oder GTK installiert hat und kein X-Server läuft.

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Methode im ThreadContext ausführen

Beitrag von Scotty »

mse hat geschrieben:Weil der Server kein Qt oder GTK installiert hat und kein X-Server läuft.
Ich kann ein Konsolenprogramm mit PostMessage() kompilieren, das kein Widgetset nutzt. Dazu muss nur die Abhängigkeit von LCLBase rein. Allerdings habe ich nicht geprüft, gegen was dann gelinkt wurde. Wenn mich nicht alles täuscht, werden diese Nachrichten auch nur innerhalb des eigenen Programmkontext ausgetauscht, so dass mir die Notwendigkeit für X nicht klar ist.
Aber Bergmann kann das ja leicht ausprobieren...

mschnell
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: Methode im ThreadContext ausführen

Beitrag von mschnell »

Scotty hat geschrieben:so dass mir die Notwendigkeit für X nicht klar ist.
Ist eigentlich auch nicht zwingend, aber die Implementierung in der LCL ist so, dass die Message-Queue nur in Verbindung mit der GUI-Anbindung (also mit API-Calls an das GUI-System) implementiert ist, weil ja auch Messages/Events aus dem Grafik-System (Tastatur, Maus, ...) im Message/Event-System - mit anderen (z.B. QueuAysncCall() ) gemischt - dem MainThread präsentiert werden müssen. Deshalb wird ist der "Wait for Event" - Mechanismus des Grafik-Systems verwendet.(Ein Erbe der ursprünglichen Implementierung auf Windows.)

Bei MSE ist der Wait-Mechanismus mit nicht-Grafischen Betriebssystem-API Calls implementiert. (Deshalb lässt sich das auch leicht auf Worker-Threads erweitern.) Die verschiedenen Event-Typen werden anscheinen beim Einschreiben in die Queue gemischt. (Bei LCL - soweit ich weiß - entweder (Windows) durch das Grafik-System selber oder (Linux) beim Auslesen aus der Queue) .

-Michael

Bergmann89
Beiträge: 98
Registriert: Di 15. Nov 2011, 11:36

Re: Methode im ThreadContext ausführen

Beitrag von Bergmann89 »

Hey,

danke für die vielen Antworten. Ich werd jetzt schnell selbst was schreiben. Meine Consolenanwendung und LCL vertragen sich nicht, da schmiert jedesmal der Linker ab, wenn ich LCL in die Abhangigkeiten mit rein nehm. Eigentlich hat die LCL ja auch nix in Consolenanwendungen zu suchen...

MfG Bergmann.

mschnell
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: Methode im ThreadContext ausführen

Beitrag von mschnell »

Bergmann89 hat geschrieben:Ich werd jetzt schnell selbst was schreiben.
Viel Erfolg. Wenn Du eine echte Event-Queue ist das mit "mal eben" nicht getan. Für eine spezielle Anwendung kannst Du das (in Linux) z.B. auf Basis von pthreadlib oder Pipes mit blocking read machen. Eine schnellere Variante (wenn Du z.B. eine Multi-Prozessor-Optimierung vor hast) wäre es FUTEX direkt zu verwenden. Das ist aber nicht trivial.

Melde Dich, wenn Du ein Ergebnis hast....

-Michael

Bergmann89
Beiträge: 98
Registriert: Di 15. Nov 2011, 11:36

Re: Methode im ThreadContext ausführen

Beitrag von Bergmann89 »

Hey,

es wird sicher keine echte EventQueue, ich leite einfach ne Klasse von TThread ab, der eine mit CriticalSections geschützte Queue hat. Dann schreib ich eine Mehtode, mit der andere Threads eine Art Message bei dem Thread abgeben können. Im Execute des Threads arbeite ich dann die Liste ab. Macht genau das was ich will und lässt sich relativ einfach implementieren...

MfG Bergmann.

Antworten