1

我正在 MAC OS 上开发应用程序。它有两部分——一个 UI 元素和一个守护进程(它需要连续运行并且必须在被杀死时重新启动)。目前我正在使用 launchctl 重新启动守护进程。

但还有另一个问题。我需要我的应用程序的 2 个部分相互通信。为此,我使用相同的分布式对象(如此给出)。但是,当我使用 launchctl 启动守护程序时,这不起作用。任何人都可以提出一些替代方案???

4

2 回答 2

2

我曾经NSDistributedNotifications在一个应用程序中很好地处理这个问题,即使在 10.7 上也是如此。您必须自己进行握手,因为这可能是有损的(即包括ack通知并在超时的情况下重新发送)。这种方法的副作用是,如果有多个客户端正在运行(特别是在快速用户切换下),它们都会收到通知。在这个应用程序的特定情况下,这很好。它的实现也非常简单。

对于另一个应用程序,我使用两个 FIFO。服务器写入一个并从另一个读取。客户则相反。当然,您也可以使用网络套接字来实现相同的目的。我倾向于更喜欢 FIFO,因为您不必处理锁定网络套接字的问题。

也就是说,您在 launchd 下使用分布式对象看到了什么问题?您是否只是在 10.7 上看到问题(它改变了启动上下文的规则)?

您是否使用 launchd 在访问端口时延迟加载守护程序(这是正常的方法)。您是否考虑过使用启动代理而不是启动守护程序?


编辑:

啊...引导服务器。是的。您需要在正确的引导上下文中执行操作才能与它们对话。登录会话的引导上下文植根于windowserver进程。LaunchDaemons 在不同的上下文中运行,因此它们不能直接与登录会话通信。一些背景阅读:

我不知道如何在不使用launchctl bsexec. Launchd 技术上有一个 API(launchctl 使用它),但它没有很好的文档记录。您可以从 opensource.apple.com拉取源代码。

即使你留下来,如果可以的话NSDistributedObject,我会尝试使用引导服务以外的东西。正如我所提到的,我倾向于使用其他工具并避免NSDistributedObject. 在我看来,与 REST 优于 SOAP 的原因相同,简单协议通常优于远程对象。(YMMV)

于 2012-02-10T17:16:29.003 回答
1

如果你使用sudo launchctl;启动你的守护进程 您不应该将CFMessagePortandDistributed object用于 IPC。CFMessagePortDistributed object使用引导服务实现(许多 Mac OS X 子系统通过与中央服务交换 Mach 消息来工作。要使这样的子系统工作,它必须能够找到该服务。这通常使用 Mach 引导服务来完成,它允许进程按名称查找服务)。如果您将使用DO or CFMessagePort; 您将遇到引导命名空间问题。何时使用 sudo launchctl 启动守护进程;您的服务已在 root bootstrap 命名空间中注册,因此您的客户端(在用户模式下运行)将无法使用该服务。
您可以使用检查引导服务

$ launchctl bslist
$ sudo launchctl bslist // If you are using sudo lunchctl

你应该使用UNIX Domain Sockets. UNIX 域套接字有点像 TCP/IP 套接字,只是通信始终是计算机本地的。您可以使用与 TCP/IP 套接字相同的 BSD 套接字 API 访问 UNIX 域套接字。主要区别在于地址格式。对于 TCP/IP 套接字,地址结构(传递给绑定、连接等的结构)是 (struct sockaddr_in),其中包含 IP 地址和端口号。对于 UNIX 域套接字,地址结构是 (struct sockaddr_un),其中包含一个路径。有关在客户端/服务器环境中使用 UNIX 域套接字的示例,请参见示例代码'CFLocalServer'
看看这篇技术说明 TN2083 Daemons and Agents
Daemon IPC Recommendations
Mach Bootstrap Basics

每个用户都有一个单独的 Mach 命名空间。您不能在命名空间之间进行通信。您将需要改用套接字 (NSSocketPort),它不受这种方式的限制。[1]

于 2012-02-10T18:12:55.153 回答