0

我有两个 GUI 应用程序,它们使用共享内存(8 个内存实例,每个约 100MB)进行频繁的读/写操作,其中一个应用程序(“服务器”)写入内存,另一个从内存中读取。在 Windows 上,“服务器”应用程序使用函数创建共享内存CreateFileMappingA,而其他应用程序使用OpenFileMappingA. 通过 访问缓冲区MapViewOfFile。锁定是通过命名互斥锁完成的。

现在我正在寻找一种在 macOS 上实现这一点的方法。XPC(尤其是xpc_shmem_map)似乎很合适,但我并不完全理解它是如何工作的。从文档和其他来源(https://developer.apple.com/forums/thread/126716)看来,我们似乎总是(?)必须创建一个服务来充当两个应用程序之间的桥梁?或者一个应用程序可以充当“服务器”(如在 Windows 上)?

在 macOS(非沙盒)上以最少的复制在两个应用程序之间共享内存的最佳方式是什么?

问候,

4

1 回答 1

1

两个应用程序本身不能通过 XPC 直接相互通信。如果您需要在 macOS 上的两个应用程序之间安全地共享内存,XPC 可能是您的最佳选择——它只需要一些额外的设置。

这里要理解的核心概念是,建立XPC连接只有两种方式:

  1. 连接到由 管理的命名服务launchd
  2. 连接到 XPC 端点。但是,进程访问与另一个服务中的侦听器连接关联的 XPC 端点的唯一方法是通过另一个XPC 连接。

您不能让一个 GUI 应用程序通过 XPC 直接连接到另一个 GUI 应用程序的原因是您的两个 GUI 应用程序都不会由launchd. 如果您想知道,我的 GUI 应用程序可以由 管理launchd吗?答案是不; launchd只管理服务(这些服务是动态启动的,如果需要系统资源可以终止)。

您需要这样做的方式是:

  1. 创建启动代理。(理论上你可以创建一个启动守护进程,但没有充分的理由——你不需要root权限来做你想做的事情。)
  2. 让您的 Launch Agent提供 XPC Mach 服务。(当我描述核心概念时,这与上面的#1相对应。)
  3. 让您的一个 GUI 应用程序创建一个匿名侦听器连接。然后获取该侦听器的端点
  4. 让该 GUI 应用程序向您的 Launch Agent 发送其端点。
  5. 让您的其他 GUI 应用程序向您的启动代理询问端点。
  6. 让其他 GUI 应用程序使用该端点创建连接

此时,您的两个 GUI 应用程序可以直接相互通信。

我描述的有点过于简单了。例如,您可以设计一种方式,让它们都创建一个匿名侦听器连接,将其发送到启动代理,如果另一个应用程序已经存在一个,则它可以返回该连接。为了避免 Launch Agent 内部的竞争条件,您可以DispatchQueue序列化其对来自 GUI 应用程序的请求的处理。

仅供参考,我链接到 API 的 Objective-C 版本,因为您的帖子标记为nsxpcconnection. 但是,所有这些也有 C API 等价物。如果你有一个跨平台的代码库,你可能会发现 C API 更容易集成。

于 2022-01-25T10:21:48.453 回答