python:简单的 dbus 示例-服务例程中的 os.fork()?

Posted

技术标签:

【中文标题】python:简单的 dbus 示例-服务例程中的 os.fork()?【英文标题】:python: simple dbus example- os.fork() in service routine? 【发布时间】:2012-06-04 07:31:06 【问题描述】:

我正在尝试编写 dbus 服务器,我想在其中运行一些外部 shell 程序(此处为grep)来完成这项工作。

当我这样做时:

prompt$ server.py

然后:

prompt$ client.py # 工作正常,即。在子进程中运行 grep 命令。

prompt$ client.py # ...,但第二次调用会产生以下错误消息:

DBusException:org.freedesktop.DBus.Error.ServiceUnknown:名称 org.example.ExampleService 不是由任何 .service 文件提供的

我被困住了。你能帮我吗?

这里是 server.py(之后是 client.py):

import gtk, glib
import os
import dbus
import dbus.service
import dbus.mainloop.glib
import subprocess

messages_queue=list()
grep_pid=0


def queue_msg(message):
    global messages_queue
    messages_queue.append(message)
    return

def dequeue_msg():
    global messages_queue,grep_pid
    if grep_pid != 0:
        try:
            pid=os.waitpid(grep_pid,os.P_NOWAIT)
        except:
            return True
        if pid[0] == 0:
            return True
        grep_pid=0

    if len(messages_queue) == 0:
            return True
    else:
            tekst=messages_queue.pop(0)

        cmd="grep 'pp'"

        print cmd
        #works fine, when I do return here
        #return True

    grep_pid=os.fork()
    if grep_pid != 0:
        return True
    os.setpgid(0,0)
    pop=subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE)
    pop.stdin.write(tekst)
    pop.stdin.close()
    pop.wait()
    exit(0)

class DemoException(dbus.DBusException):
    _dbus_error_name = 'org.example.Exception'

class MyServer(dbus.service.Object):

    @dbus.service.method("org.example.ExampleInterface",
                         in_signature='', out_signature='')
    def QueueMsg(self):
            queue_msg("ppppp")

    @dbus.service.method("org.example.ExampleInterface",
                         in_signature='', out_signature='')
    def Exit(self):
        mainloop.quit()

from dbus.mainloop.glib import threads_init

if __name__ == '__main__':
        glib.threads_init()

        threads_init()

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

        session_bus = dbus.SessionBus()
        name = dbus.service.BusName("org.example.ExampleService", session_bus)
        object = MyServer(session_bus, '/My')

        glib.timeout_add_seconds(1, dequeue_msg)
        mainloop = glib.MainLoop()
        print "Running example service."
        mainloop.run()

现在是client.py:

import sys
from traceback import print_exc
import dbus

def main():
    bus = dbus.SessionBus()

    try:
        remote_object = bus.get_object("org.example.ExampleService",
                                       "/My")

    except dbus.DBusException:
        print_exc()
        sys.exit(1)

    iface = dbus.Interface(remote_object, "org.example.ExampleInterface")

    iface.QueueMsg()

    if sys.argv[1:] == ['--exit-service']:
        iface.Exit()

if __name__ == '__main__':
    main()

【问题讨论】:

我一直在研究如何将应用程序与 dbus-python 集成并遇到您的帖子。如果您向下滚动一点,则此link 中有一个部分,称为“自定义主循环迭代”。它是关于定制 glib mainloop ;) 以及它如何与 *nix 系统上的fork 不兼容。 【参考方案1】:

当您尝试访问不再可用的服务时,您通常会收到此错误消息。检查您的服务器是否仍在运行。

您可以使用d-feet 来调试您的 dbus 连接。

【讨论】:

【参考方案2】:

关于缺少.service文件的错误信息意味着您需要在dbus-1/services中创建一个服务文件。

例如:

# /usr/local/share/dbus-1/services/org.example.ExampleService.service
[D-BUS Service]
Name=org.example.ExampleService
Exec=/home/user1401567/service.py

很多教程都没有包含这个细节(也许 .service 文件过去不是必需的?)但是,至少在 Ubuntu 12.04 上,没有它就无法连接 dbus 服务。

【讨论】:

能否请您添加一些教程资源?我无法通过网络搜索找到它(我猜是我的错)。它曾经在没有任何这些 .service 文件的情况下为我工作,但现在突然停止工作 - 不知道为什么。 (或者甚至更好,为我提供正确的搜索关键字,这样下次我会更成功地搜索:)?)

以上是关于python:简单的 dbus 示例-服务例程中的 os.fork()?的主要内容,如果未能解决你的问题,请参考以下文章

ActiveX 多线程调用 javascript 回调例程中的问题

简单(但具体)的侦听器和发送器 Python 3 DBus 示例

rpc Call 方法是不是与服务器在同一个 go 例程中运行?

Python协程中的并行异步IO

dbus c:啥绑定(gdbus?)和客户端/服务器简单示例

从 VBA 中的另一个子例程中抑制 MsgBox