"[xcb] Unknown request in queue while dequeuing" killt pygame App

  • Hallo,

    mir wurde hier schon wunderbar geholfen, erst einmal danke dafür!

    ich habe aktuell ein kleines Python Programm das via PIR Sensor eine Bewegung detektiert, dann einen Effekt Sound abspielt und ein LED sequenz dazu abspielt, wird keine Bewegung erkannt gibts eine Athmo und einen andere LED Sequenz.

    Die LED Steuerung habe ich mal rausgenommen, im Prinzip simulieren die LEDS ein Feuergewaber.

    Jetzt bekomme ich nach ca einer Stunden Laufzeit, manchmal auch früher die Fehlermeldung:

    [xcb] Unknown request in queue while dequeuing

    [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called

    [xcb] Aborting, sorry about that.

    python3: ../../src/xcb_io.c:165: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.

    die letzte Ausgabe in der console ist:play fire aktion sound

    den Code habe ich angehängt. es wäre super hilfreich wenn mir jemand sagen könnte in welche Richtung ich hier suchen soll.

    Grüße

  • "[xcb] Unknown request in queue while dequeuing" killt pygame App? Schau mal ob du hier fündig wirst!

  • mindthegap GUIs sind in der Regel nicht thread-sicher. Das gilt auch für Pygame. In dem `pir_callback()` darf man nichts an der GUI verändern, das kann sonst zu komischen Verhalten bis hin zu harten Abstürzen führen.

    Bei solchen Callbacks aus anderen Threads macht man am besten nicht viel, sondern signalisiert das nur an das Hauptprogramm.`pygame.event.post()` ist thread-sicher, man könnte sich also hier ein eigenes Event in die Hauptschleife schicken, und dann dort entsprechend darauf reagieren.

    Sonstiges: Es gibt zu viel Code auf Modulebene. Da sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

    Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • mindthegap Weitere Anmerkungen: ``global`` bitte gleich wieder vergessen.

    Importe stehen üblicherweise am Anfang des Moduls und nicht irgendwo versteckt mittendrin. Damit man leichter sehen kann was die Abhängigkeiten sind.

    `random` wird importiert, aber nirgends verwendet.

    Sternchen-Importe sind Böse™. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.

    ``as`` beim Importieren ist zum umbenennen gedacht, aber `GPIO` wird gar nicht umbenannt.

    ``sys.argv[0]`` ist nicht wirklich geeignet um den Pfad zum Programm zu ermitteln. Den Pfad zum aktuellen Modul ermittelt man über `__file__`.

    Anstelle der `os.path`-Funktionen verwendet man in neuem Code eher das `pathlib`-Modul.

    `LED_PRO_BLOCK`, `LED_BLOCKS`, `LED_BASERIGHT`, `LED_LEFT`, `LED_RIGHT`, `LED_LOWTIME`, `LED_HIGHTIME`, `LED_LOW`, `LED_HIGH`, `maxRandom`, `distorsion`, `distorsionLow`, `LED_LOWTIMERANGE`, `LED_HIGHTIMERANGE`, `MUSIC_ON` werden definiert, aber nicht wirklich irgendwo verwendet. Und `LED_BASELEFT` wird auch nicht wirklich verwendet, weil da ausschliesslich eine Farbe drin steckt in der Liste.

    Die Funktion `allean()` wird definiert, aber nirgends verwendet. Sollte sie aber vielleicht, denn im Hauptprogramm steht noch mal Code der das gleiche macht. Die Funktion `alleaus()` ist nahezu eine Kopie von `allean()` und hat deshalb einen inhaltlich falschen Docstring. Kopieren und leicht anpassen von Code ist ein Warnzeichen, dass man das anders lösen möchte. Zum Beispiel durch eine Funktion und/oder eine Schleife. In diesem Fall will man einfach die Funktion von `allean()` von `alleaus()` heraus verwenden.

    Da sind ein paar sinnlose ``time.sleep(0.1)`` im Code verteilt‽

    `GPIO.cleanup()` sollte am Ende des Programms aufgerufen werden. Und auch das ``--clear``-Argument sollte am Programmende auf jeden Fall ausgewertet werden, an *einer* Stelle, nicht an zwei verschiedenen. `pygame.quit()` gehört dort auch hin.

    Das ``try``/``except KeyboardInterrupt:`` ist an der falschen Stelle, denn das bricht die ``while``-Schleife nicht ab.

    Man vergleicht nicht mit literalen Wahrheitswerten, denn da kommt nur wieder ein Wahrheitswert bei heraus. Entweder der, den man sowieso schon hatte, dann hätte man gleich den verwenden können. Oder dessen Gegenteil. Dafür gibt es ``not``.

    Da sind drei Tests auf `playSound` mit Code dazwischen. Das lässt sich zu einem Test zusammenfassen.

    `pygame.init()` wird nur aufgerufen wenn `playSound` wahr ist. Das macht keinen Sinn. Und wenn kein Sound ausgewählt ist, dann funktioniert auch das Zurückschalten von Rot nach Grün nicht, weil das am Ende der Soundausgabe passiert.

    Statt `left` und `right` überall im Programm zu testen, kann man eine Liste mit Strips anlegen und die einfach abarbeiten.

    Das zeichnen eines farbigen Kreises steht dreimal fast identisch im Quelltext. Ein Kandidat für eine Funktion.

    Ungetestet:

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!