queue+threads

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
frank-w
User
Beiträge: 21
Registriert: Freitag 19. Februar 2021, 18:38

__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
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
frank-w
User
Beiträge: 21
Registriert: Freitag 19. Februar 2021, 18:38

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
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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)
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
frank-w
User
Beiträge: 21
Registriert: Freitag 19. Februar 2021, 18:38

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
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

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.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten