Wie in GUI einen Thread abfragem
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Wie in GUI einen Thread abfragem
Hallo zusammen,
ich habe in einem GUI Mainprogramm mehrere Threads in denen serielle Schnittstelle verarbeitet werden.
Momentan polle ich über einen Timer die Threads ab, ob da was empfangen wurde.
Funktioniert so auch.
Was mich jetzt interresieren würde, wie kann ich von einem der Threads selber einen
Event erzeugen um nicht pollen zu müssen.
Ich hab da nicht mal einen Ansatz nach dem ich gockeln könnte.
Könnte mir jemand einen Ansatz für so etwas zeigen nach dem ich suchen kann?
Danke schon mal im Vorraus
Gruß
NoCee
ich habe in einem GUI Mainprogramm mehrere Threads in denen serielle Schnittstelle verarbeitet werden.
Momentan polle ich über einen Timer die Threads ab, ob da was empfangen wurde.
Funktioniert so auch.
Was mich jetzt interresieren würde, wie kann ich von einem der Threads selber einen
Event erzeugen um nicht pollen zu müssen.
Ich hab da nicht mal einen Ansatz nach dem ich gockeln könnte.
Könnte mir jemand einen Ansatz für so etwas zeigen nach dem ich suchen kann?
Danke schon mal im Vorraus
Gruß
NoCee
Zuletzt geändert von theo am Di 24. Sep 2019, 09:04, insgesamt 1-mal geändert.
Grund: Korrektur für die Suchfunktion (Threat -> Thread)
Grund: Korrektur für die Suchfunktion (Threat -> Thread)
- corpsman
- Lazarusforum e. V.
- Beiträge: 1619
- Registriert: Sa 28. Feb 2009, 08:54
- OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
- CPU-Target: 64Bit
- Wohnort: Stuttgart
- Kontaktdaten:
Re: Wie in GUI einen Threat abfragem
Das Stichwirt heist
Synchronize, kannst mal auf meiner HP ( http://www.Corpsman.de )nach dem Beispiel Race Condition suchen, dort wird gezeigt wie man es Richtig (aber auch Falsch machen) kann.
Aus dem Sample interessiert dich die Routine "IncPrimeCount".
Kurz zusammengefasst.
Wenn du aus einem Thread heraus auf die GUI zugreifen willst, musst du das in einer Synchronized Routine machen, Anstatt die (Parameterlose) Prozedur direkt auf zu Rufen schreibst du :
Du kannst dann von IncPrimeCount aus direkt auf die LCL zugreifen, da die Prozedur innerhalb des Mainthread aufgerufen wird. Dein eigentlicher Thread wartet in der Zwischenzeit.
Synchronize, kannst mal auf meiner HP ( http://www.Corpsman.de )nach dem Beispiel Race Condition suchen, dort wird gezeigt wie man es Richtig (aber auch Falsch machen) kann.
Aus dem Sample interessiert dich die Routine "IncPrimeCount".
Kurz zusammengefasst.
Wenn du aus einem Thread heraus auf die GUI zugreifen willst, musst du das in einer Synchronized Routine machen, Anstatt die (Parameterlose) Prozedur direkt auf zu Rufen schreibst du :
Code: Alles auswählen
Procedure TPrimeSynchronized.IncPrimeCount;
Begin
inc(PrimeCount); // Zugriff auf LCL erlaubt, informationen müssen via Private Variablen des Threads rein gereicht werden.
End;
..TThread.execute..
..
Synchronize(@IncPrimeCount);
..
--
Just try it
Just try it
-
- 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 in GUI einen Threat abfragem
TThread.Synchronize ruft eine Funktion im GUI Thread auf und blockiert den aufrufenden Thread so lange, bis die Funktion abgearbeitet ist. Dadurch kann es nicht passieren, dass unerwünschte Effekte durch parallelen Zugriff auf gemeinsame Datenstrukturen auftreten. Allerdings wird der Thread u.U. beliebig lange aufgehalten und kann demzufolge nicht mehr sicher auf seine Trigger (z.B. die Serielle Schnittstelle) reagieren.
TThread.Queue ruft eine Funktion im GUI Thread auf, während der Thread parallel weiterläutf. Man muss selber darauf achten, dass es nicht passiert, das unerwünschte Effekte durch parallelen Zugriff auf gemeinsame Datenstrukturen auftreten.
-Michael
TThread.Queue ruft eine Funktion im GUI Thread auf, während der Thread parallel weiterläutf. Man muss selber darauf achten, dass es nicht passiert, das unerwünschte Effekte durch parallelen Zugriff auf gemeinsame Datenstrukturen auftreten.
-Michael
-
- Beiträge: 2118
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Wie in GUI einen Threat abfragem
Du kannst das ganze auch einfach umdrehen, statt im Worker infos aus dem GUI abzufragen kannst du ganz einfach im GUI thread, wenn sich infos ändern, den Worker benachrichtigen. Das ganze dann noch über Critical Sections sperren. Somit musst du nicht irgendwie code in den Mainthread einschläusen (wie es synchronize oder TThread.Queue macht).
Wenn du jetzt immer die property SomeData verwendest (und nie FSomeData direkt) ist jeder zugriff gesichert, und in deinem GUI kannst du ganz einfach da reinschreiben:
Code: Alles auswählen
TWorker = class(TThread)
private
FSomeData: TSomeData;
FSomeDataCS: TRTLCriticalSection;
function getSomeData: TSomeData;
procedure setSomeData(const newData: TSomeData);
...
public
property SomeData: TSomeData read getSomeData write setSomeData;
...
end;
...
function TWorker.getSomeData: TSomeData;
begin
// wird benötigt wenn FSomeData kein atomarer datentyp ist
// wenn es einer ist, ist eine CS nicht notwendig
EnterCriticalSection(FsomeDataCS);
try
Result := FSomeData;
finally
LeaveCriticalSection(FSomeDataCS)
end;
end;
procedure TWorker.setSomeData(const newData: TSomeData);
begin
// wird benötigt wenn FSomeData kein atomarer datentyp ist
// wenn es einer ist, ist eine CS nicht notwendig
EnterCriticalSection(FsomeDataCS);
try
FSomeData := newData;
finally
LeaveCriticalSection(FSomeDataCS)
end;
end;
...
Code: Alles auswählen
procedure TForm1.Edit1Change(Sender: TObject);
begin
// Angenommen SomeData ist vom typen String
Worker.SomeData := Edit1.Text;
end;
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Re: Wie in GUI einen Thread abfragem
Danke schon mal für die Antworten.
Ich hab jetzt einiges im Netz suchen und lesen können.
Synchronize... ist soweit ich das jetzt kapiert habe für meinen Fall nicht das richtige.
Es soll möglichst kein Thread warten müssen.
Bisher hab ich im Maintread mit einem Timer einen String von den Workerthreads abgefragt ob da irgend etwas drinsteht.
Gesichtert über Critical Section.
Der Gedanke war aus dem Worker eine Prozedur im Mainthread aufzurufen wenn Daten vollständig im Worker da sind.
Unterwegs hab ich jetzt aber den Faden verloren.
Kann ich eine Prozedur vom Main in einem Worker aufrufen?
Die Daten muß ich gegenseitig verriegeln ok, aber eine Prozedur?
Über TThread.Queue hab ich bisher noch nichts gefunden was ich kapiert hätte. Leider das meiste in englisch.
Kann ich zwar, aber da fallen noch viel mehr Wörter die ich noch nicht kenne.
Unterwegs bin ich dann noch auf eine Komponente gestoßen die auf Synaser basiert. Sdpo.
Die machen das aber auch mit Synchronize. Aber da ist schon mal ein komplettes Beispiel dabei.
Gruß
NoCee
Ich hab jetzt einiges im Netz suchen und lesen können.
Synchronize... ist soweit ich das jetzt kapiert habe für meinen Fall nicht das richtige.
Es soll möglichst kein Thread warten müssen.
Bisher hab ich im Maintread mit einem Timer einen String von den Workerthreads abgefragt ob da irgend etwas drinsteht.
Gesichtert über Critical Section.
Der Gedanke war aus dem Worker eine Prozedur im Mainthread aufzurufen wenn Daten vollständig im Worker da sind.
Unterwegs hab ich jetzt aber den Faden verloren.
Kann ich eine Prozedur vom Main in einem Worker aufrufen?
Die Daten muß ich gegenseitig verriegeln ok, aber eine Prozedur?
Über TThread.Queue hab ich bisher noch nichts gefunden was ich kapiert hätte. Leider das meiste in englisch.
Kann ich zwar, aber da fallen noch viel mehr Wörter die ich noch nicht kenne.
Unterwegs bin ich dann noch auf eine Komponente gestoßen die auf Synaser basiert. Sdpo.
Die machen das aber auch mit Synchronize. Aber da ist schon mal ein komplettes Beispiel dabei.
Gruß
NoCee
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Re: Wie in GUI einen Thread abfragem
Hallo zusammen,
ich hab jetzt einiges über TThread.Queue gelesen.
An einer Stelle stand da, das TThread.Queue einen Eintrag in der Mainthread Eventqueue macht.
Das wäre dann eigentlich genau das was ich mir vorgestellt hatte.
Im Event wird dann meine Procedure aufgerufen. Das werd ich mal versuchen
hinzubekommen.
Was mir da nicht einleuchtet, da steht dann ...Queue(@blabla..
Warum steht da immer der Adressoperator?
Der Compilere kennt doch mein komplettes Programm.
Warum muß ich hier mit der Adresse arbeiten?
Danke schon mal für eine Antwort
Gruß NoCee
ich hab jetzt einiges über TThread.Queue gelesen.
An einer Stelle stand da, das TThread.Queue einen Eintrag in der Mainthread Eventqueue macht.
Das wäre dann eigentlich genau das was ich mir vorgestellt hatte.
Im Event wird dann meine Procedure aufgerufen. Das werd ich mal versuchen
hinzubekommen.
Was mir da nicht einleuchtet, da steht dann ...Queue(@blabla..
Warum steht da immer der Adressoperator?
Der Compilere kennt doch mein komplettes Programm.
Warum muß ich hier mit der Adresse arbeiten?
Danke schon mal für eine Antwort
Gruß NoCee
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Wie in GUI einen Thread abfragem
Über den Adressoperator kannst du dem Compiler unterschiedliches sagen:NoCee hat geschrieben:Was mir da nicht einleuchtet, da steht dann ...Queue(@blabla..
Warum steht da immer der Adressoperator?
Der Compilere kennt doch mein komplettes Programm.
Warum muß ich hier mit der Adresse arbeiten?
- blabla - Rufe die Funktion blabla auf und übergebe deren Rückgabe an TThread.Queue
- @blabla - Übergebe die Adresse der Methode blabal an TThread.Queue
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- 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 in GUI einen Thread abfragem
... Wie immer, wenn man eine Funktion/Prozedur als Parameter übergibt. Da ist bei Queue() nichts besonderes.
-Michael
-Michael