Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 主循环、事件循环在DBus服务中的作用_Python_Python 3.x_Dbus_Pyqt5 - Fatal编程技术网

Python 主循环、事件循环在DBus服务中的作用

Python 主循环、事件循环在DBus服务中的作用,python,python-3.x,dbus,pyqt5,Python,Python 3.x,Dbus,Pyqt5,这是DBus服务的标准示例 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.Ob

这是DBus服务的标准示例

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()
我对此处使用的两个主回路有疑问
1.在这段代码中,每个主循环或事件循环的作用是什么(如果我使用的是正确的术语。我猜它们都是事件循环)
2.如果我的应用程序不是GUI应用程序,为什么我需要gobject mainloop或qt mainloop,因为这是从X11库捕获用户生成的事件所必需的(在Linux的情况下)
3.为什么我不能使用一个不做任何事情的无限循环来代替gobject主循环(如下所示)


以下是简短的答案摘要,更多解释请参见末尾的详细信息

问题1:

您发布的代码中只使用了一个mainloop,即
loop=gobject.mainloop()
。它的作用是处理事件,例如发送到您的服务的D-Bus消息

问题2:

您需要一个mainloop,以便代码不会阻止来自服务外部的D-Bus消息。
dbus-python
绑定没有mainloop实现,因此您需要使用其他库中的mainloop(在本例中,它也需要是受
dbus-python
支持的库)

问题3:

像这样的无限循环将永远不允许执行除该特定循环之外的任何代码,并且将无法接收D-Bus消息(或任何其他事件)

详细信息:

简单地说,当程序中当前没有代码运行时,mainloop通常会处理其他事件。在这种情况下,D-Bus的性质要求您的代码有一种方法来处理来自外部源的事件,即D-Bus消息。这就是您需要一个mainloop的原因。您可以基于自己编写的循环来处理事件,只要循环中有可以处理外部事件的代码。人们经常将库用于主循环的原因是,在“真实”的应用程序或系统中,事情往往变得越来越复杂,而使用已经被他人测试、使用和改进多年的东西(例如GLib)通常会更加健壮

D-Bus绑定
dbus-python
的实现方式需要使用外部mainloop,因为它没有自己的mainloop实现。设计使用外部mainloop的库的一个典型原因是让库的用户决定使用哪个mainloop,因为mainloop也可能用于其他事情(例如,处理D-Bus事件以外的其他事件)。这增加了库的潜在使用,并减少了作为使用库的副作用引入的依赖项

然而,库必须支持所选的mainloop,这意味着必须为打算与库一起使用的每个mainloop提供特定的集成。通常,像这样的库的内部将被设计为使用作为mainloop抽象的类/类型,因此代码内部不需要知道集成了什么mainloop。这减少了库中需要特定于mainloop实现的代码量

如果在执行以下操作时检查接收到的
总线\u循环
对象:

bus_loop = DBusGMainLoop(set_as_default=True)
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
loop.run()
。。。您将看到它是一个类型为
dbus.mainloop.NativeMainLoop
的对象,它是
dbus python
中的mainloop包装对象

现在,
dbuspython
目前只为glibmainloop提供了一个集成,因此在这种情况下,上面的讨论有点理论化。
dbus-python
集成GLib-mainloop的方法是要求用户导入并实例化GLib-mainloop包装器,如下所示:

from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
loop.run()
这将创建一个GLib主上下文,GLib主循环稍后使用该上下文来处理与该上下文关联的事件。mainloop集成的最后一部分是要求用户启动GLib mainloop。导入并运行
gobject
main循环时,如下所示:

from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
loop.run()
mainloop将处理来自先前创建的上下文的事件。这是D-Bus绑定
dbus-python
和GObject绑定
GObject
之间的“链接”(它提供对GLib主循环的访问)

简化到极致,可以说在执行以下操作时创建和设置了上下文:

bus_loop = DBusGMainLoop(set_as_default=True)
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
loop.run()
是要处理的事件列表(如果出现),以及执行以下操作时创建和启动的主循环:

bus_loop = DBusGMainLoop(set_as_default=True)
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
loop.run()
是什么让某些东西检查这个列表。简单地说,GLib同时用于这两个方面,这一事实使它能够工作


如果你想更深入地了解这一点,请阅读GLib、GmailOOP和GMainContext以及与之相关的概念。希望这有帮助。

谢谢您的回答。它把事情弄清楚了一点。如果我正确理解了您的答案,我可以说gobject.Mainloop()包含侦听DBus生成的事件的代码,即gobject.Mainloop()明确提供了对DBus的支持。我猜DBus python在使用时会检查它的“默认Mainloop”,在本例中,它在之前被设置为GLib。因此dbus-python为GLib-mainloop提供了一个集成,并且知道如何连接到该集成中,因此GLib-mainloop通过调用dbus-python来处理D-Bus事件。因此,仍然是dbus-python在做D-Bus工作,但它使用GLib在事件中被调用。从这个意义上讲,dbus-python提供了对GLib的支持,而不是相反。将D-Bus和mainloop创建分离的一个原因是,您可能希望在同一个程序中使用mainloop进行其他操作。我更新了我的答案,试图更好地解释其中涉及的概念。希望能有帮助。(另外,如果有帮助,请接受答案:))