Gui-Anderung einer Eigenschaft in einem anderen Modul

Fragen zu Tkinter.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

jerch hat geschrieben:@Alfons:
Wie alt bist Du eigentlich? Die Angriffe auf Personen stärken nicht Deine Argumente sondern machen DICH lächerlich. Dachte eigentlich, Du hättest meine Anspielung weiter oben verstanden, aber das Sandkastenniveau musste wohl trotzdem her.

1+ fürs Sperren.
Angriffe? BlackJack ist es, der laufend angreift und nicht auf die Antworten eingeht, sondern ständig wieder dasselbe bringt. Und schreibt, dass ich es beweisen müsste. Und jetzt beginnt wohl wieder der allgemeine Angriff von Dir und von anderen auf mich? Und dann wohl wieder sperren?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Alfons Mittelmeyer hat geschrieben:Angriffe? BlackJack ist es, der laufend angreift und nicht auf die Antworten eingeht, sondern ständig wieder dasselbe bringt. Und schreibt, dass ich es beweisen müsste. Und jetzt beginnt wohl wieder der allgemeine Angriff von Dir und von anderen auf mich? Und dann wohl wieder sperren?
Bisher war es im Prinzip nie notwendig hier Thread zu sperren. Eigentlich hatten wir auch immer einen recht Freundlichen Tonfall... Doch seid du da bist, ist das in deinen Threads irgendwie nicht mehr so. Das sollte dir zu denken geben.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@Alfons Mittelmeyer: Van Rossum schreibt da das er keine Ahnung vom Thema hat und das ihm das Pollen, was seiner Beobachtung nach anscheinend *alle* machen nicht gefällt. Dem widerspreche ich jetzt wo genau?

Ich habe nicht behauptet das Pollen mit `after()` eine schöne Lösung ist. Nur das es die gängige Praxis ist. Und offensichtlich aus dem Grund das es das einzige ist was threadsicher ist, weil Tcl/Tk laut dessen Dokumentation *grundsätzlich* nur aus einem Thread heraus benutzt werden darf, also insgesamt *nicht* threadsicher ist. Da bleibt ja nur das Pollen aus dem einen Thread heraus den man verwenden darf.

Ich greife eine technisch kaputte ”Lösung” an. Du wirst persönlich und pampig weil es Dir anscheinend nicht gefällt das Du hundert Zeilen ach so genialen Code produziert hast, der nicht threadsicher ist, aber eben genau für den Einsatz von mehreren Threads gedacht ist.
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

jens hat geschrieben:Bisher war es im Prinzip nie notwendig hier Thread zu sperren. Eigentlich hatten wir auch immer einen recht Freundlichen Tonfall... Doch seid du da bist, ist das in deinen Threads irgendwie nicht mehr so. Das sollte dir zu denken geben.
Das stimmt jetzt aber auch nicht so ganz. Hier sind über die Jahre immer wieder mal irgendwelche skurrilen Typen aufgetaucht und ab und zu waren auch Threadsperrungen nötig.

Ich stimme der Kritik am Code von Alfons und zum Teil auch der Kritik an ihm als Person durchaus zu. Aber man sollte IMHO aufpassen, dass man nicht ins pure Bashing abgleitet.

Meiner Meinung nach dürften wir alle vernünftig genug sein, um Personen, die uns möglicherweise missfallen, *nicht* unbegründet zu schikanieren. Wie gesagt: Kritik an Codeschnipseln halte ich für berechtigt (wie die Person das aufnimmt, steht auf einem anderen Blatt). Kritik an bestimmten - konkret benannten - Äußerungen geht ebenfalls in Ordnung. Aber Alfons nun als das größte Übel von allen hinzustellen, finde ich doch arg übertrieben.
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: etwas erwiesenermaßen threadsicher zu programmieren ist schwierig. Quasi unmöglich wird es, wenn externe Bibliotheken zum Einsatz kommen, die nachweislich nicht threadsicher sind. Dann bleibt eigentlich nur, zu garantieren, dass nur EIN EINZIGER Thread auf diese Bibliothek zugreift.

event_generate hat zwei Modi:
1. direkt ausführen (ohne when=): da sieht auch jemand ohne Erfahrung im Thread-Programmieren, dass das nicht gut geht.
2. verzögert ausführen (mit when=): da denkt jemand, der keine Erfahrung im Thread-Programmieren hat, dass sich das doch gut anhört.

Dazu muß aber das Event in eine Queue eingetragen werden, also in Pseudo-Code ungefähr das:

Code: Alles auswählen

QUEUE[INDEX] = EVENT
INDEX += 1
Wenn das jetzt zwei Threads A und B gleichzeitig machen wollen, kann das passieren:

Code: Alles auswählen

A: QUEUE[INDEX] = EVENT_A
B: QUEUE[INDEX] = EVENT_B
B: INDEX += 1
A: INDEX += 1
Event B überschreibt Event A und wir haben ein uninitialisiertes Element in der Queue. Im besten Fall stürzt das Programm jetzt ab. Das heißt nicht threadsicher und soetwas kann so oder so ähnlich bei Tk immer passieren, wenn man mit Threads nicht aufpasst.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Alfons Mittelmeyer hat geschrieben:Und schreibt, dass ich es beweisen müsste.
Nun ja, das ist allgemein so üblich, dass derjenige in der Beweispflicht steht, der von der Norm abweichende Thesen aufstellt ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

Zumal es hier darum geht das behauptet wird dort würde etwas existieren. Also kann man das ja auch zeigen. Umgekehrt kann ich nicht beweisen das es nicht existiert weil da ja eben nichts ist auf das ich zeigen könnte.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Sirius3 Finde ich gut, dass Du es sachlich angehst. Das wäre aber dann einen eigenen Thread hier wert, nämlich wie sicher ist die Tcl/Tk Event Queue. Es kann ja sein, dass jemand die Maus bewegt, während er sich nicht in der Tcl/Tk Task befindet. Der Maus Handler - in einer anderen Task, und das ist sogar normal - schreibt aber das Maus Event in diese Event Queue. Kann es dann passieren, dass bei Bewegung der Maus oder beim Klicken das System abstürzt, weil wir uns gerade nicht in der Tcl/Tk Task befinden?

Da müßte man sehr in die Implementierungsdetails gehen und diese Event Queue und den Befehl event_generate, den es dann auch in C etwa für den Maus Handler gibt, genauer untersuchen.

Die andere Frage wäre dann auch, was ist mit after? After soll ja nicht die mainloop aufwecken. Was ist, wenn wir etwas während after etwas machen, das etwa <Configure> betrifft. Hat das dann einen Effekt oder nicht?

Also was meinst Du, sollte man besser die Maus nicht klicken, weil das eventuell nicht threadsicher wäre und das System dabei abstürzen könnte? Denn genau darum geht es, ein Event in diese Queue zu schreiben.
Also nach Meinung von einigen sollte man es wohl besser unterlassen, die Maus zu klicken, solange es nicht bewiesen ist, dass das threadsicher ist.
BlackJack

@Alfons Mittelmeyer: Man muss da eben nicht in die Implementierungsdetails gehen denn die sind nicht die öffentliche Programmierschnittstelle. Das ist ja gerade die wichtige Eigenschaft von Implementierungsdetails, das man sich nicht auf sie verlassen kann und darf. Öffentlich ist die Informationen das man den Tcl-Interpreter nur von einem Thread aus benutzen darf. Damit ist alles gesagt was man wissen muss. Wer es doch tut schreibt Code der funktionieren kann, aber nicht muss, und schlicht und einfach falsch ist.

Edit:Die Ereignisse für Mausklicks werden Tk-intern in diese Queue geschrieben, also innerhalb des Threads in dem die Hauptschleife läuft, womit das sicher ist weil daran nur dieser eine Thread beteiligt ist.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:Öffentlich ist die Informationen das man den Tcl-Interpreter nur von einem Thread aus benutzen darf. Damit ist alles gesagt was man wissen muss. Wer es doch tut schreibt Code der funktionieren kann, aber nicht muss, und schlicht und einfach falsch ist.
Bitte erkennen, begreifen, verstehen. Damit man den Tcl-Interpreter in dem richtigen Thread verwendet, schreibt man nur etwas in die Queue von ihm und weckt ihn dadurch auf. Und daher habe ich das mit dem Event genau richtig implementiert.
BlackJack hat geschrieben:Edit:Die Ereignisse für Mausklicks werden Tk-intern in diese Queue geschrieben, also innerhalb des Threads in dem die Hauptschleife läuft, womit das sicher ist weil daran nur dieser eine Thread beteiligt ist.
Das ist ebenfalls nicht wahr. Das hieße ja, solange Du Dich nicht in dem Thread der Hauptschleife befindest, kannst Du klicken, was Du willst und es passiert nichts. Also kann man tkinter vergessen, weil Du klicken kannst was Du willst, ohne jeden Effekt. Richtig ist, dass man erst etwas in die Queue schreiben muß, um die mainloop aufzuwecken.

Und was macht event_generate? Genau dasselbe, was ich bei den anderen Threads getan habe:

Code: Alles auswählen

    def send(self,msgid,msgdata=None):
        self.Queue.put((msgid,msgdata))
        self.event.set()
Schreibt etwas in eine threadsichere Queue und setzt das event des Threads, damit der aus dem lock von wait() in der Event loop aufwacht.
Statt send, musst Du Dir eben event_generate vorstellen, wenn Du dazu in der Lage bist.
BlackJack

@Alfons Mittelmeyer: Jetzt fängst Du an absoluten Unsinn zu schreiben. Du schreibst etwas in die Queue vom Tcl-Interpreter und weckst dadurch dessen Thread auf? Wieso sollte der denn ”schlafen”? Gewagte Annahme würde ich mal sagen. Fakt ist das die Dokumentation sagt man darf die Funktionen von dem Tcl-Interpreter nur von einem Thread aus benutzen. Du verwendest `event_generate()` aber von einem anderen aus. Also genau falsch implementiert.

Die Erklärung mit den Mausklicks ist auch totaler Unsinn. Wenn die `mainloop()` läuft (und die muss man nicht aufwecken) dann wird darin irgendwo intern dafür gesorgt das die Mausklicks auf dem jeweiligen System als Ereignisse in die Ereigniswarteschlange landen und dann ebenfalls durch die `mainloop()` abgearbeitet werden. Also alles in dem einen Thread in dem die `mainloop()` läuft. Die dazu nicht aufgeweckt werden muss bzw. falls da doch intern eine Benachrichtigung passiert, dann passiert sie eben genau so: intern. Und das kann auch je nach System anders implementiert sein, weil das ja auch davon abhängt wie man an die entsprechenden Systemereignisse heran kommt. Eben Implementierungsdetails.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:Jetzt fängst Du an absoluten Unsinn zu schreiben. Du schreibst etwas in die Queue vom Tcl-Interpreter und weckst dadurch dessen Thread auf? Wieso sollte der denn ”schlafen”? Gewagte Annahme würde ich mal sagen.
Warum er schläft? Weil professionelle Programmierer keinen Unsinn programmieren und nicht so etwas machen, wie in einer Endlosschleife ständig pollen:

Code: Alles auswählen

while True: self.work()
Endlosschleifen kosten Rechenzeitig, weil sie ständig laufen. Man macht das genau so, wie ich es getan habe:

Code: Alles auswählen

while True:
    self.event.wait()
    while self.work(): pass
Wenn nichts mehr zu tun ist, legt ein Thread sich schlafen, bis er durch ein Event wieder aufgeweckt wird. Von Programmierung verstehst Du anscheinend nicht viel.
BlackJack hat geschrieben:Fakt ist das die Dokumentation sagt man darf die Funktionen von dem Tcl-Interpreter nur von einem Thread aus benutzen. Du verwendest `event_generate()` aber von einem anderen aus. Also genau falsch implementiert.
Also kapiere das doch endlich einmal: event_generate ist nicht der Tcl-Interpreter sondern 'self.event.set()' (mit vorherigem Schreiben in die threadsichere Queue) womit der Tcl-Interpreter aus dem wait() seines Schlafes erwacht.
Und der Rest? Wenn Du nicht fähig bist, etwas zu verstehen, dann höre auf ständig damit weiter zu machen.

Manche verstehen eben nur Endlosschleife und pollen, eventuell verlangsamt durch sleep oder after. Und empfehlen pollen in einer Schleife.
Zuletzt geändert von Alfons Mittelmeyer am Donnerstag 3. September 2015, 17:00, insgesamt 2-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Also im Vergleich zu dem, was BlackJack sich hier teilweise anhören darf, bin ich ja erstaunt, wir ruhig er dabei bleibt... :D
Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

Ich auch.
Am Anfang hab ich ja gedacht, dass der Alfons trollt. Ich bin mir nicht sicher, ob ich das nicht sogar besser gefunden hätte.
"Ein Geisterfahrer? Hunderte!"
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@sparrow: Zumindest mit ``del`` hat er für mich eindeutig getrollt. Normalerweise wissen Trolle ja, dass sie Unsinn von sich geben. In diesem Fall war es aber eher eine Art Trollen aus Überzeugung.

Und aktuell ist es eher ein Mischmasch, bei dem Alfons mit seinen 2 Monaten an Python-Erfahrung natürlich stets die klügsten Ideen hat. ;)
BlackJack

@Alfons Mittelmeyer: Du weiss nicht ob der Tcl/Tk-Thread in der Hauptschleife gerade schläft oder nicht und falls er schläft auch nicht ob er durch `event_generate()` aufgeweckt wird oder nicht. Und vor allem kannst Du Dir nicht sicher sein das der Thread gerade in dem Augenblick schläft während Du ein `event_generate()` von einem anderen Thread aus ausführst, denn er kann ja just in dem Augenblick wach sein weil er ein Systemereignis verarbeiten muss, oder irgendetwas anderes was innerhalb des Threads passiert von dem aus legal auf den Tcl-Interpreter zugegriffen werden darf.

Dein `self.event` und Deine Queue haben nichts mit der threadsicherheit des Tcl-Interpreters zu tun. Das Du die Python-Seite von Deiner kaputten Lösung absicherst macht die Gesamtlösung nicht sicher weil `event_generate()` unsicher ist und Du das auch nicht sicher hinbekommst weil Du an die Interna vom Tcl-Interpreter gar nicht heran kommst.

Ich verstehe das der Tcl-Interpreter explizit dokumentiert nicht threadsicher ist, und zwar pauschal wirklich gar nicht, und damit pollen die einzige Möglichkeit ist. Das ist ein Fakt und keine Meinung. Das kannst Du auch nicht mit persönlichen Angriffen wegdiskutieren. Ich verstehe genug vom Programmieren, sowohl vom Studium als auch davor und danach durch langjährige Praxis.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@BlackJack Ich mag nicht mehr, weil es nichts bringt, jemand etwas erklären zu wollen, der es anscheinend nicht begreifen kann. Mein Rat, halte Dich an das, was professionelle Programmierer, wie Guido van Rossum dazu geschrieben haben:
From: Guido van Rossum <gui...@python.org>
Wed, 6 Nov 2013 16:39:16 -0800

Hi Kevin,

Thanks for the clarification.

Fortunately using event_generate() with a virtual event works like a charm
(unlike after() or after_idle()) so I am happy with the way things are now.
It has been quite frustrating though to get here. :-(

--Guido
Quelle: http://code.activestate.com/lists/pytho ... cuss/3493/
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: das Problem mit Deinem Mailings-Link ist, dass Du die Zwischentöne nicht mitgelesen hast. Da ist ein Guido van Rossum der aus irgendeinem Grund einmal ein Tk-Programm schreiben wollte, aber bei dessen Umsetzung am Verzweifeln ist. Dann etliche Poster, die irgendwelche Halbwahrheiten aus dem Internet gezogen haben, die beim einen funktionieren, bei anderen wieder nicht. Es gibt keinen Weihnachtsmann und im Internet stehen nicht nur gut recherchierte und wahre Artikel.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Alfons Mittelmeyer: das Problem mit Deinem Mailings-Link ist, dass Du die Zwischentöne nicht mitgelesen hast. Da ist ein Guido van Rossum der aus irgendeinem Grund einmal ein Tk-Programm schreiben wollte, aber bei dessen Umsetzung am Verzweifeln ist. Dann etliche Poster, die irgendwelche Halbwahrheiten aus dem Internet gezogen haben, die beim einen funktionieren, bei anderen wieder nicht. Es gibt keinen Weihnachtsmann und im Internet stehen nicht nur gut recherchierte und wahre Artikel.
Etliche Poster, die Halbwahrheiten aus dem Internet beziehen? Das ist eine hochrangige Expertenrunde. Wer ist zum Beispiel Kevin Walzer? Chef Core Entwickler für Tcl/Tk System für Mac OS X. Und solche Experten wissen genau, was Sache ist. Also hört endlich mal mit dem Trollen auf.

Und das Problem mit after und after_idle ist, dass man da nicht die mainloop aufweckt, sondern noch zusätzlich die Maus bewegen muss, um dann sporadisch GUI updates zu bekommen. Zumindest gibt es diese Probleme bei manchen Tcl/Tk Versionen und in manchen Fällen.

Ihr wollt doch nicht ernsthaft behaupten, dass Guido van Rossum sich nicht mit Python auskennnt und nur Halbwahrheiten aus dem Internet bezogen hat und bei Kevin Walzer ist es dasselbe in Bezug auf Tcl/Tk?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

`event_generate` sollte in CPython threadesafe sein. Der Aufruf wird intern über `tk.call` abgesetzt, welcher hier implementiert ist: https://github.com/python/cpython/blob/ ... er.c#L1509. Der Code unter `#ifdef WITH_THREAD` macht im Prinzip das, was die Tcl-Doku für messaging zwischen Threads vorsieht.

Fraglich ist, ob andere Pythonvarianten das auch umsetzen. Mit PyPy zumindest funktioniert es nicht.
Antworten