__deets__ hat geschrieben:
Abgesehen davon ist das fuer die Widerlegung deiner Behauptung nicht notwendig: mein Code reicht um zu zeigen, dass deine Theorie vom nur durch sleep(..) freizugebenden GIL Unfug ist. Das wuerde dann schon bei meinem Minimalbeispiel nicht klappen. Tut's aber, der Fehler liegt also bei dir - wo auch immer...
Sorry, dass ich das nicht bis in das Detail behandelt hatte,
'nur' durch sleep stimmt natürlich nicht. Es gibt auch Events und eine Event Queue und Events, wie binding an einen command und timer wie after werden natürlich behandelt. Hatte ja geschrieben, dass das mit 'after' und Abholen von der Queue klappt. Nur die Nachbearbeitung des Bildaufbaus durch tkinter also nach der Ausführung des Python codes, die klappt dann nicht mehr. Also nochmals- die Events werden abgearbeitet, nur nachdem der Python Code des Events abgearbeitet ist, ist Sense und tkinter kann den Bildaufbau nicht mehr machen. Endlich kapiert??? Also: Python meldet, der event ist fertig - doch tkinter ist noch nicht fertig, das ist das Problem hier.
Alfons Mittelmeyer hat geschrieben:
Ach so, jedes Mal ein neuer Thread. Ist da viel Unterschied, ob man den alten Thread in der Thread Queue drin läßt, oder ihn rauswirft (beendet) und wieder über einen Timer reinhängt?
__deets__ hat geschrieben:
Lass mich mal kurz ueberlegen... ein Systemaufruf (select mit timeout)
https://github.com/python/cpython/blob/ ... le.c#L1444
vs einen neuen Thread anlegen (pthread_create), ein Condition-Objekt erzeugen, das hat ein Lock, etc etc etc... da kommen vielleicht ein dutzend teilweise recht komplexen Systemcalls zusammen, mit Resourcen-Anforderderungen diverser Natur.
Ja. Ist viel mehr Code. Ist deutlich mehr Aufwand. Bringt genau gar nix (fuer diesen Use-case). Aber du darfst das gefuehlt natuerlich besser finden, ist ja wichtig, das man sich im Recht *fuehlt*, nicht, das man es ist... QED dieser Thread (no pun intended).
Ja dieser Timer vom Threading gefällt mir auch nicht. Man sollte da lieber den after Timer von tkinter nehmen. Den kann man über event.set() auch mit anderen Threads verbinden.
Allerdings stellt sich jetzt dann die Frage, wozu ein anderer Thread.
Es gibt zwei grundsätzliche Konzepte:
- Es ist eine tkinter Anwendung: dann hat so ein anderer Thread nichts darin zu suchen und man nimmt einfach after ohne neuen Thread
- Die GUI könnte eine beliebige GUI sein, z.B. tkinter oder auch Qt oder eine andere.
Dann haben aber solche Bindings überhaupt nichts darin zu suchen:
self.screen.window.bind('<1>', self.on_L)
Außerdem diese locks sind völlig unsinnig:
Code: Alles auswählen
def on_L(self, e):
self.gedrueckt_lock.acquire()
self.gedrueckt = -1
self.gedrueckt_lock.release()
Außer dem Mousebutton 1 ruft das niemand auf.
Genauso ist dieser Lock völlig unsinnig:
Code: Alles auswählen
def schritt(self):
# Ball seitwärts
self.gedrueckt_lock.acquire()
Außer in hauptschleife wird das nirgendwo anders aufgerufen.
Da das so ein Mischmasch ohne klares Konzept ist - und zudem mit nicht funktionierenden locks, ist zu empfehlen, den Thread ganz rauszuwerfen:
Code: Alles auswählen
'''
def hauptschleife(self):
zeit = time()
while self.spiel_laeuft:
while time()-zeit < 1/FPS:
sleep(0)
#pass
zeit += 1/FPS
self.schritt()
self.ausgabe()
'''
def hauptschleife(self):
self.screen.window.after(int(1000/FPS),self.hauptschleife)
self.schritt()
self.ausgabe()
rr = Rapid_Roll()
#Thread(target=rr.hauptschleife).start()
rr.hauptschleife()
rr.screen.mainloop()
Das hätte dann auch die beste Performance.
Auch after(1,...) in canvas_screen.py macht keinen Sinn. Für Werte unter 10 gibt es nicht den geringsten Grund.