Rolle von Mainloops, Event Loops im DBus Service

Dies ist das Standardbeispiel für den DBus-Service.

import dbus import gobject from dbus import service # from gi._gobject import MainLoop from dbus.mainloop.glib import DBusGMainLoop class DBusServer(service.Object): def __init__(self, name, object_path): # super(service.Object, self).__init__(name, object_path) dbus.service.Object.__init__(self, name, object_path) @dbus.service.method("com.test", in_signature='s', out_signature="s") def test(self, args): return args + " Sent by dbus client" @dbus.service.method("com.test", in_signature='s', out_signature="s") def foo(self, args): return "foo" bus_loop = DBusGMainLoop(set_as_default=True) session_bus = dbus.SessionBus() session_name = service.BusName("com.test", session_bus) dbus_server = DBusServer(session_name, "/test") loop = gobject.MainLoop() try: loop.run() except KeyboardInterrupt: loop.quit() 

Ich habe Fragen zu zwei hier eingesetzten Mainloops
1. Was ist die Rolle jedes Mainloop oder Event-Loop in diesem Code (wenn ich die richtige Terminologie verwende.Sie sind beide Event-Loops, denke ich)
2. Wenn meine App keine GUI-App ist, warum sollte ich gobject mainloop oder qt mainloop benötigen, da dies erforderlich ist, um User generierte Events aus der X11-Bibliothek zu fangen (im Falle von Linux)
3. Warum kann ich nicht eine Endlosschleife verwenden, die anstatt der Gobjekt-Hauptschleife nichts macht (wie folgt)

 while True: pass 

One Solution collect form web for “Rolle von Mainloops, Event Loops im DBus Service”

Im Folgenden sind kurze Antworten zusammengefasst, siehe die Details am Ende für weitere Erklärungen.

Frage 1:

Es gibt nur einen mainloop, der in dem Code verwendet wird, den du gepostet hast, die loop = gobject.MainLoop() . Seine Aufgabe ist es, Ereignisse zu verarbeiten, z. B. D-Bus-Nachrichten, die an Ihren Dienst gesendet werden.

Frage 2:

Sie benötigen einen mainloop, damit Ihr Code keine D-Bus-Nachrichten von außerhalb Ihres Dienstes auslöst. Die dbus-python Bindung hat keine Mainloop-Implementierung, so dass Sie einen Mainloop aus einer anderen Bibliothek nutzen müssen (die auch von dbus-python , in diesem Fall GLib unterstützt werden muss).

Frage 3:

Eine unendliche Schleife wie diese wird niemals erlauben, dass ein anderer Code als diese bestimmte Schleife ausgeführt wird, und es würde keine Möglichkeit geben, D-Bus-Nachrichten (oder andere Ereignisse) zu empfangen.

Details:

Einfach ausgedrückt, ein Mainloop verarbeitet normalerweise andere Ereignisse, wenn es keinen Code gibt, der momentan in deinem Programm läuft. In diesem Fall erfordert die Art von D-Bus, dass es einen Weg für Ihren Code gibt, um Ereignisse aus einer externen Quelle zu behandeln, dh D-Bus-Nachrichten. Dies ist der Grund, dass Sie einen mainloop haben müssen. Sie können die Ereignisverarbeitung auf einer Schleife basieren, die Sie selbst schreiben, solange Sie Code in der Schleife haben, der externe Ereignisse verarbeiten kann. Der Grund, warum Menschen oft Bibliotheken für Mainloops verwenden, ist, weil die Dinge in "echten" Anwendungen oder Systemen komplex werden, und es ist oft robuster, etwas zu verwenden, das seit Jahren (zB GLib) getestet, verwendet und verbessert wurde.

Die D-Bus Bindung dbus-python ist in einer Weise implementiert, die eine externe Mainloop verwendet werden muss, da es keine eigene Mainloop-Implementierung hat. Ein typischer Grund für das Entwerfen einer Bibliothek, um einen externen mainloop zu benutzen, besteht darin, den Benutzer einer Bibliothek zu entscheiden, welche Mainloop zu bedienen ist, da der Mainloop möglicherweise auch für andere Dinge verwendet werden könnte (zB andere Ereignisse als D-Bus-Ereignisse verarbeiten). Dies erhöht die potenzielle Nutzung der Bibliothek und reduziert die Abhängigkeiten als Nebenwirkung der Verwendung der Bibliothek eingeführt.

Die Bibliothek muss jedoch das Mainloop der Wahl unterstützen, was bedeutet, dass es eine gewisse Integration geben muss, die speziell für jedes Mainloop vorgesehen ist, das für die Verwendung der Bibliothek bestimmt ist. Typischerweise würden die Interna einer solchen Bibliothek so entworfen, dass sie eine Klasse / einen Typ verwenden, der eine Abstraktion eines Mainloops ist, so dass die Code-Interna nicht wissen müssen, welche Mainloop integriert wurde. Dies verringert die Menge an Code, der in der Bibliothek eine Mainloop-Implementierung sein muss.

Wenn Sie das bus_loop Objekt bei der bus_loop untersuchen:

 bus_loop = DBusGMainLoop(set_as_default=True) 

… sie werden sehen, dass es ein Objekt vom Typ dbus.mainloop.NativeMainLoop welches das Mainloop-Wrapper-Objekt in dbus-python .

Nun bietet dbus-python derzeit nur eine Integration für den GLib-Mainloop, so dass die Diskussion oben in diesem Fall ein bisschen theoretisch wird. Die Art und Weise, wie dbus-python ein GLib-Mainloop integriert, ist, dass der Benutzer den GLib-Mainloop-Wrapper importieren und instanziieren muss:

 from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) 

Dies schafft einen GLib-Hauptkontext, der später von einem GLib-Mainloop verwendet wird, um Ereignisse zu verarbeiten, die dbus-python mit diesem Kontext verknüpft. Der letzte Teil der Mainloop-Integration besteht darin, dass der Benutzer einen GLib-Mainloop starten muss. Wenn du den gobject mainloop importierst und renst, wie folgt:

 loop = gobject.MainLoop() loop.run() 

Der mainloop verarbeitet Ereignisse aus dem zuvor erstellten Kontext. Dies ist die "Verknüpfung" zwischen der D-Bus-Bindungs- dbus-python und dem GObject-Bindungs- gobject (das den Zugriff auf das GLib-Mainloop ermöglicht).

Vereinfacht auf das Äußere, könnte man sagen, dass der Kontext erstellt und gesetzt, wenn dabei:

 from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True) 

Ist eine Liste der Ereignisse zu verarbeiten, wenn sie erscheinen, und die mainloop erstellt und begann, wenn Sie:

 loop = gobject.MainLoop() loop.run() 

Ist was macht etwas überprüfen diese Liste. Die Tatsache, dass GLib für beide Sachen verwendet wird, macht es funktionieren, wieder einfach.

Wenn du weiter darüber nachdenken willst, lest auf GLib und den GMainLoop und GMainContext und die damit zusammenhängenden Konzepte auf. Hoffe das hilft.

  • Wie bekomme ich den Namen / die Datei des Skripts von sitecustomize.py?
  • Python - Virtualenv, Python 3?
  • Ausgabe mit Einsparung in einen Txt in Python 3.3.2
  • Pythonic beautifulSoup4: Wie bekomme ich noch Titeln von der nächsten Seite Link einer Wikipedia-Kategorie
  • Python3-Submodul-Setup aktualisiert keine Pfade, wenn mit -m-Switch ausgeführt wird
  • Python Gruppe zwei Listen
  • Gleicher Code langsamer in Python3 im Vergleich zu Python2
  • Das installierte Python-Skript kann keine Paketmodule importieren
  • Wie man "ValueError: gelesen von geschlossener Datei" in python 3.5.1 zu überwinden
  • Verwenden Sie Regex, um Informationen aus einem bestimmten Textformat zu erhalten
  • Aufruffunktion in einer anderen Klasse durch Kivy Button
  • Python ist die beste Programmiersprache der Welt.