Seite 2 von 2
Re: queue+threads
Verfasst: Montag 16. August 2021, 10:28
von frank-w
__blackjack__ hat geschrieben: Montag 16. August 2021, 10:03
@frank-w: Ich würde das ohne `empty()` machen, mit einer ``while True:``-Schleife die dann verlassen wird wenn das `get_nowait()` eine Ausnahme auslöst weil die Queue tatsächlich leer ist.
Welchen Vorteil hat das? Aus meiner Sicht macht es den code größer und schwerer verstehbar
Re: queue+threads
Verfasst: Montag 16. August 2021, 11:17
von __blackjack__
@frank-w: Bei `empty()` steht „This method is likely to be removed at some point.“ in der Dokumentation. Es ist eben nicht ganz ohne Probleme das zwischen dem Aufruf von `empty()` und dem `get()` sich noch etwas am Zustand der Queue ändern kann.
Viel grösser und komplizierter wird der Code dadurch nicht:
Code: Alles auswählen
def sync_ui(self):
while True:
try:
item = self.doneq.get_nowait()
except queue.Empty:
self.scrolltxt.insert(tk.END, "no more jobs\n")
break
try:
self.scrolltxt.insert(tk.END, f"{item}\n")
finally:
self.doneq.task_done()
self.scrolltxt.see(tk.END)
self.win.after(200, self.sync_ui)
Das ``try``/``finally`` habe ich da eingefügt damit der `join()` auf der Queue der ja irgendwo stehen muss, nicht endlos wartet wenn beim Code im ``try``-Block eine Ausnahme auftreten sollte. Falls `join()` gar nicht verwendet wird braucht es auch `task_done()` nicht, und damit auch das ``try``/``finally`` nicht und der Code wird ein bisschen einfacher.
Re: queue+threads
Verfasst: Montag 16. August 2021, 11:56
von frank-w
Die Logik ist jetzt aber anders....
Ich habe ja 2 queues...
- eine UI => thread (aka jobs,self.q)
- Rückmeldung des threads,welche fertig sind (self.doneq) für die Anzeige
Die Anzeige,dass nichts mehr zu tun ist,basiert auf der ersten Queue (Arbeitsvorrat des Threads).
Dein Ansatz nimmt ggf. dem Thread die Jobs weg (wenn man das empty des Arbeitsvorrates genauso implementiert).
Join verwende ich (aktuell) nicht
Re: queue+threads
Verfasst: Montag 16. August 2021, 14:39
von __blackjack__
@frank-w: Okay, dann muss das in einen ``else``-Zweig:
Code: Alles auswählen
def sync_ui(self):
while True:
try:
item = self.doneq.get_nowait()
except queue.Empty:
break
else:
try:
self.scrolltxt.insert(tk.END, f"{item}\n")
finally:
self.doneq.task_done()
if self.q.qsize() == 0:
self.scrolltxt.insert(tk.END, "no waiting jobs\n")
self.scrolltxt.see(tk.END)
self.win.after(200, self.sync_ui)
Re: queue+threads
Verfasst: Montag 16. August 2021, 16:06
von frank-w
Mhm,unten verwendest du qsize...würde doch oben auch funktionieren,oder?
Sehe hier keinen deprecated hinweis
https://docs.python.org/3/library/queue.html
Das no waiting jobs müsste eigentlich nach der while sein (bei mir auch falsch) und wird evtl.zu zeitig (jobliste könnte schon leer sein,aber die letzte rückmeldungnoch nicht in doneq) und immer wieder angezeigt (sollten mehr rückmeldungen eintreffen durch mehrere threads).
Da muss ich mir nochmal Gedanken machen
Re: queue+threads
Verfasst: Montag 16. August 2021, 17:56
von __blackjack__
Ich schaue bei so etwas was ich einfach in der Python-Shell importieren kann immer in die Docstrings:
https://github.com/python/cpython/blob/ ... eue.py#L97
`qsize()` ist auch nicht besser, aber das steht halt bei `empty()` im Docstring.