0

我有一个用 python 编写的 LaunchDaemon,它以 root 权限执行长时间且资源密集型的后台任务。当它工作时,它需要向多个 GUI 代理(每个登录用户一个)发送状态更新,我正在努力寻找合适的 IPC 机制。由于守护程序和代理在不同的引导上下文中运行,因此共享对象将不起作用。我不能让守护进程打开一个套接字,因为它无法长时间回复,并且客户端必须轮询更新。我想出的最好的办法是让每个代理打开自己的套接字,然后守护进程依次向每个代理写入,但这充其量似乎是不雅的。还有其他选择吗?哦,它必须在 Mac OS X 10.5 及更高版本上运行。

4

1 回答 1

0

我最终让每个 GUI 代理在 /tmp 下创建一个数据报套接字,然后启动守护程序依次向每个代理发送一条消息并清理陈旧的套接字:

SOCKET_DIR = "/tmp"
SOCKET_NAME = "se.gu.it.dafgu_migration_status"

status_socket = None

def set_status_menu(status, message):
    global status_socket
    try:
        if status_socket is None:
            status_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        if status_socket is not None:
            message = serializePlist({
                "DAFGUMigrationStatus": status,
                "DAFGUMigrationMessage": message,
            })
            for item in os.listdir(SOCKET_DIR):
                if item.startswith(SOCKET_NAME):
                    socket_path = os.path.join(SOCKET_DIR, item)
                    logging.debug("Sending message to %s" % socket_path)
                    try:
                        status_socket.sendto(message, socket_path)
                    except socket.error, e:
                        if e[0] == errno.ECONNREFUSED:
                            logging.info("Removing stale socket %s" % socket_path)
                            os.unlink(socket_path)
                        else:
                            logging.warn("Sending to %s failed: %s" % (socket_path, e))
    except BaseException, e:
        logging.debug("Unhandled exception when updating status menu: %s" % e)

完整的实现可以在 github 上找到:

于 2012-11-19T09:19:32.710 回答