DBus-Cherrypy 合并问题

Posted

技术标签:

【中文标题】DBus-Cherrypy 合并问题【英文标题】:DBus-Cherrypy merge issue 【发布时间】:2010-12-30 21:39:40 【问题描述】:

我正在使用 python-dbus 和 cherrypy 来监控 USB 设备并提供 REST 服务来维护插入的 USB 设备的状态。我已经独立编写和调试了这些服务,它们按预期工作。

现在,我将这些服务合并到一个应用程序中。我的问题是: 我似乎无法同时启动两种服务(cherrypy 和 dbus)。一个或另一个阻塞或超出范围,或未初始化。

我已经尝试将每个都封装在自己的线程中,然后对它们调用 start 。这有一些奇怪的问题。

class RESTThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        cherrypy.config.update( 'server.socket_host': HVR_Common.DBUS_SERVER_ADDR, 'server.socket_port': HVR_Common.DBUS_SERVER_PORT, )
        cherrypy.quickstart(USBRest())

class DBUSThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        DBusGMainLoop(set_as_default=True)
        loop = gobject.MainLoop()
        DeviceAddedListener()
        print 'Starting DBus'
        loop.run()

print 'DBus Python Started'
if __name__ == '__main__':
    # Start up REST

    print 'Starting REST'
    rs = RESTThread()
    rs.start()

    db = DBUSThread()
    db.start()

    #cherrypy.config.update( 'server.socket_host': HVR_Common.DBUS_SERVER_ADDR, 'server.socket_port': HVR_Common.DBUS_SERVER_PORT, )
    #cherrypy.quickstart(USBRest())

    while True:
        x = 1

运行此代码时,cherrypy 代码未完全初始化。当插入 USB 设备时,cherrypy 继续初始化(好像线程以某种方式链接),但不起作用(不提供数据甚至在端口上建立连接)我查看了 cherrypys wiki 页面但是还没有找到一种启动cherrypy的方法,它可以初始化并返回,所以我可以初始化DBus的东西并能够把它拿出来。

我的终极问题是:有没有办法让cherrypy 启动而不阻塞但继续工作?我想摆脱这个例子中的线程,并在主线程中初始化cherrypy和dbus。

【问题讨论】:

我试过这个:***.com/questions/510821/… 现在,cherrypy 工作得很好,但 loop.run() 似乎不起作用。 【参考方案1】:

是的;不要使用cherrypy.quickstart。相反,解压它:

cherrypy.config.update(conf)
cherrypy.tree.mount(USBREST())
cherrypy.engine.start()

Quickstart 执行上述操作,但通过调用 engine.block() 完成。如果您的程序有 CherryPy 以外的其他主循环,请省略对 engine.block 的调用,您应该没问题。但是,当您的外部主循环终止时,您仍然需要调用cherrypy.engine.stop():

loop = gobject.MainLoop()
try:
    loop.run()
finally:
    cherrypy.engine.stop()

还有一些其他的问题,比如 CherryPy 是否应该处理 Ctrl-C 和其他信号,以及它是否应该自动重新加载。这些行为取决于您,并且都相当容易启用/禁用。查看其中一些的cherrypy.quickstart() 源代码。

【讨论】:

我试过这个,几种方法都没有成功。我确实设法找出问题所在。显然,在进行一系列 thread_init() 调用之前,启动一个 glib 循环(对于 DBus messenger )不会让任何其他线程在应用程序中启动。我将在原帖中详细说明这一点。您的解决方案适用于不存在新 glib 循环的情况。【参考方案2】:

我想通了。显然,glib 中有一堆线程争用问题。如果您制作的应用程序中包含 DBusGMainLoop,则您无法在应用程序中创建另一个线程。新线程在调用 start() 时立即阻塞。再多的按摩也不会让新线程运行。

我发现一个站点对 dbus.mainloop.glib.threads_init() 有一个模糊的引用,以及在初始化新线程之前必须如何调用它。然而,当尝试这样做时,发现了一个新问题。抛出一个异常,说 g_thread_init() 必须在 dbus.mainloop.glib.threads_init() 被调用之前被调用。更多搜索发现了对 gobject.threads_init() 的另一个模糊引用。它似乎很合适,所以经过多次实验,我发现了正确的顺序。

这是解决方案。

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
gobject.threads_init()
dbus.mainloop.glib.threads_init()    
DBUSMAINLOOP = gobject.MainLoop()

print 'Creating DBus Thread'
DBUSLOOPTHREAD = threading.Thread(name='glib_mainloop', target=DBUSMAINLOOP.run)
DBUSLOOPTHREAD.start()

print 'Starting REST'
cherrypy.config.update( 'server.socket_host': Common.DBUS_SERVER_ADDR, 'server.socket_port': Common.DBUS_SERVER_PORT, )
cherrypy.quickstart(USBRest())

天哪,真是一场噩梦。现在让它变得更好。

【讨论】:

以上是关于DBus-Cherrypy 合并问题的主要内容,如果未能解决你的问题,请参考以下文章

合并、取消合并、重新合并宏

Easy Ui 中的单元格合并问题

列表合并问题:在一定条件下合并二维数组

dp之沙子合并 环形沙子合并 沙子合并加强 沙子三兄弟的故事

Table问题:请问怎么合并上下的两个单元格???

如何合并(记住合并不合并!)这两个查询[关闭]