主循环,事件循环在DBus服务中的作用 [英] Role of Mainloops, Event Loops in DBus service

查看:153
本文介绍了主循环,事件循环在DBus服务中的作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是DBus服务的标准示例。

This is the standard example of 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()

我对这里使用的两个主循环有疑问

1.此代码中每个主循环或事件循环的作用是什么(如果我正在使用正确的术语。我猜它们都是事件循环。

2.如果我的应用程序不是GUI应用程序,为什么我需要gobject mainloop或qt mainloop,因为从X11库捕获用户生成的事件是必需的(如果Linux)

3.为什么不能使用不执行任何操作的无限循环代替gobject主循环(如下所示)

I have questions regarding two mainloops used here
1. What is the role of each mainloop or event loop in this code (if I am using the correct terminology. They both are event loops I guess)
2. If my app is not a GUI app why should I need gobject mainloop or qt mainloop since that is required to catch user generated events from X11 library (in case of Linux)
3. Why can't I use an infinite loop which does nothing instead of gobject main loop (as follows)

while True:
    pass


推荐答案

下面总结了简短的答案,请参阅末尾的详细信息以获取更多说明。

Below are summarized short answers, see the details at the end for more explanations.

问题1:

在您发布的代码中仅使用了一个主循环, loop = gobject.MainLoop()。它的作用是处理事件,例如D-Bus消息已发送到您的服务。

There is only one mainloop being used in the code you posted, the loop = gobject.MainLoop(). Its role is to process events, e.g. D-Bus messages sent to your service.

问题2:

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

You need a mainloop in order for your code to not block D-Bus messages coming from outside your service. The dbus-python binding does not have a mainloop implementation so you need to use a mainloop from some other library (which also needs to be one supported by dbus-python, in this case GLib).

问题3:

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

An infinite loop like that will never allow for any code other than that particular loop to execute, and there would be no way of receiving D-Bus messages (or any other events).

详细信息:

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

Simply put, a mainloop typically processes other events when there is no code currently running in your program. In this case, the nature of D-Bus requires there to be a way for your code to handle events from an external source, i.e. D-Bus messages. This is the reason that you need to have a mainloop. You could base the event processing on a loop you write yourself, as long as you have code in the loop that can process external events. The reason people often use libraries for mainloops is because things tend to grow complex in 'real' applications or systems and it's often more robust to use something which has been tested, used, and improved by others for years (e.g. GLib).

D-Bus绑定 dbus-python 的实现方式需要使用外部mainloop,因为它没有自己的mainloop实现。设计库以使用外部mainloop的典型原因是让库的用户决定要使用哪个mainloop,因为mainloop可能还用于其他用途(例如,处理D-Bus事件以外的其他事件)。这增加了对该库的潜在使用,并减少了由于使用该库而带来的依赖性。

The D-Bus binding dbus-python is implemented in a way that requires an external mainloop to be used, as it does not have its own mainloop implementation. A typical reason for designing a library to use an external mainloop is to let the user of a library decide what mainloop to use, since the mainloop could potentially be used for other things as well (e.g. process other events than D-Bus events). This increases the potential use of the library and reduces the dependencies introduced as a side-effect of using the library.

但是,该库必须支持所选的主循环,这意味着必须为打算与该库一起使用的每个主循环专门提供一些集成。通常,像这样的库的内部结构将设计为使用类/类型,该类/类型是mainloop的抽象,因此代码内部结构不需要知道已集成了哪些mainloop。这样可以减少库中特定于主循环实现的代码量。

The library must however support the mainloop of choice which means that there must be some integration provided specifically for each mainloop intended to be used with the library. Typically, the internals of a library like this would be designed to use a class/type that is an abstraction of a mainloop so the code internals doesn't need to know about what mainloop has been integrated. This reduces the amount of code which needs to be mainloop implementation specific within the library.

如果您检查 bus_loop 在执行操作时收到的对象:

If you examine the bus_loop object received when doing:

bus_loop = DBusGMainLoop(set_as_default=True)

...,您会看到它是 dbus.mainloop.NativeMainLoop 类型的对象 dbus-python 中的mainloop包装对象。

... you will see that it is an object of type dbus.mainloop.NativeMainLoop which is the mainloop wrapper object in dbus-python.

现在, dbus-python 当前仅提供GLib主循环的集成,因此在这种情况下,上面的讨论变得有些理论化。 dbus-python 集成GLib mainloop的方式是要求用户导入和实例化GLib mainloop包装器,如下所示:

Now, dbus-python currently only provides an integration for the GLib mainloop so the discussion above becomes a bit theoretical in this case. The way dbus-python integrates a GLib mainloop is to require the user to import and instantiate the GLib mainloop wrapper, like this:

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

这将创建GLib主上下文,随后GLib主循环将其用于处理 dbus-python 与该上下文关联的事件。 mainloop集成的最后一部分是要求用户启动GLib mainloop。当您导入并运行 gobject 主循环时,如下所示:

This creates a GLib main context which is later used by a GLib mainloop to process events that dbus-python associates with that context. The last part of the mainloop integration is to require the user to start a GLib mainloop. When you import and run the gobject mainloop, like this:

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

mainloop将处理来自先前创建的上下文。这是D-Bus绑定 dbus-python 与GObject绑定 gobject 之间的链接(可访问

The mainloop will process events from the context created previously. This is the 'link' between the D-Bus binding dbus-python and the GObject binding gobject (which gives access to the GLib mainloop).

可以简化为一个极端,可以说上下文是在执行操作时创建并设置的:

Simplified to the extreme, one could say that the context created and set when doing:

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

是事件发生时要处理的列表,并在执行操作时创建并启动mainloop:

is a list of events to process if they appear, and the mainloop created and started when doing:

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

是什么做一些检查该列表。

is what makes something check that list. The fact that GLib is used for both things makes it work, again simply put.

如果要进一步研究它,请继续阅读GLib以及GMainLoop和GMainContext。以及与此相关的概念。希望这会有所帮助。

If you want to dig further into this, read up on GLib and the GMainLoop and GMainContext and the concepts related to these. Hope this helps.

这篇关于主循环,事件循环在DBus服务中的作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆