进程间的通信

阅读The Complete Friday Q&A:Volume I 第2天
进程间通信(Interprocess Communication)

IPC是一个有趣的,有时是复杂的话题,尤其是在OS X上,它拥有真正的IPC技术库。很难决定要使用哪个,有时甚至很难知道可用的东西.

OS X是Mach与UNIX混合产物,因此您最终会同时使用两种IPC机制:

1、Mach端口:Mach中的基本IPC机制。快速,轻巧,功能强大且难以使用。Mach端口不仅使您可以与其他进程进行对话,而且还可以将代码强行注入其他人的程序中。Mach文档的糟糕状态使其难以上手,并且容易出错。另一方面,核心mach_msg函数可能是系统中最优化的syscall,因此它们的使用速度非常快,如果您决定一次分配一百万个mach的端口,您的机器几乎眨眼就能完成。

  • CFMachPort:Mach端口的简单封装。CFMachPort本质上是作为runloop的源而存在。它还可以帮助创建和销毁端口。它只有在接收消息方面有一点作用,而在发送消息方面没有任何作用。
  • CFMessagePort:这个很好的CoreFoundation包装器包含一些马赫功能,可以轻松地在两个不相关的进程之间建立同步的来回通信。您仅需几行代码即可启动服务器。然后,另一个程序可以通过名称查找该服务器并向其发送消息。您将获得马赫数的速度优势,而无需在下面进行所有杂乱的工作。
  • NSPort / NSMachPort / NSMessagePort:Cocoa也有一些Mach端口的封装。它们主要是为与分布式对象一起使用而设计的(在下文中有更多介绍),但是如果您勇敢的话,也可以单独使用它们。

2、POSIX文件描述符:实际上有几种,但是一旦设置,它们就可以与典型的读写调用一起使用。

  • 管道:原型POSIX IPC机制。如果您曾经使用过|在UNIX Shell中使用管道运算符,您已经使用了管道。管道是在同一流程中成对创建的,因此它们对于在父级和子级之间(或在一个单独的,协调的父级的两个子级之间)进行通信非常有用,但对于在不相关的进程之间进行通信则不太好。打电话给他们。
  • FIFO:就像文件一样,但是就像管道! FIFO就像文件一样在您的文件系统中获得一个条目,但是写操作不会进入文件系统,而是会进入打开fifo进行读取的任何过程。您可以通过mkfifo调用进行制作。最终结果是一个具有文件系统条目的管道,这可以使两个不相关的进程很容易进行连接。这些过程甚至不必知道自己正在与Fifo交谈。在您的外壳中尝试一下:
  • Sockets:您可能通过使用TCP / IP知道了这些信息,但是它们也可以用于本地通信,而不仅仅是连接到本地主机。如果在AF_UNIX系列中创建套接字,则将获得仅用于本地通信的套接字,并且使用比TCP / IP允许的更为灵活的寻址方式。通过使用套接字和绑定调用,可以使用类似于FIFO的文件系统路径来创建AF_UNIX套接字,但是允许多个客户端以及更多通信方式选择。也可以使用socketpair调用匿名创建它们,从而为您提供类似于管道的东西,但双向除外。

3、共享内存:共享内存是一种神奇的内存,可以一次出现在多个进程中。换句话说,您从过程A中写入数据,并在过程B中对其进行读取,反之亦然。这往往非常快,因为数据本身从不接触内核,也不必复制。缺点是协调共享内存区域的更改确实很困难。本质上,您可以将线程编程的所有缺点以及将多进程编程的大多数缺点捆绑在一个简单的程序包中。可以使用mach或POSIX API创建共享内存。

4、Miscellaneous,而不是真正的IPC:有些技术并没有真正算作“ IPC”,但如果需要,可以用于在程序之间进行通信。

  • ptrace:此系统调用主要用于编写调试器,但从理论上讲,它也可以用于执行非调试器。不推荐,仅出于完整性考虑。
  • Files:有时使用纯旧文件进行通信可能会很有用。这可以很简单,例如创建一个互斥的锁定文件(一个简单的空文件,只需在该文件中即可工作),或者可以通过将实际数据写到一个文件中,然后让另一个程序读取它来传输实际数据。由于您实际上是在写文件系统,所以这往往效率很低,但是它也很容易并且几乎是通用的。每个应用程序都可以读取文件!

这些就是我所说的系统级功能,它们要么是内核/ libSystem直接提供的,要么是它们周围的薄包装。 OS X在框架级别还提供了一堆更高级别的IPC机制:

4、Apple Events:天空之灾,丑陋比赛的冠军,慢王,恐怖帝王。 Apple Events就是所有这些东西,但是它们也非常有用。它们是Mac OS X上用于远程控制的GUI应用程序普遍支持的唯一IPC机制。是否要告诉另一个应用程序打开文件?苹果活动的时间。是否要告诉另一个应用程序正常退出? Apple活动时间。最重要的是,Apple Events是基于mach端口构建的,但是API中并未对此进行公开。

  • AppleScript:Apple Events的所有情况都在变坏,但仍然经常有用,AppleScript是一种基于Apple Events的脚本语言。通常,最好避免直接使用AppleScript,而是直接或通过诸如Scripting Bridge之类的机制发送相应的原始Apple Events。 AppleScript支持是允许用户编写您的应用程序脚本的标准方法,尽管如果您尝试向应用程序中添加AppleScript支持,则会发现自己希望使用其他标准。

5、分布式对象:就像Objective-C,但它发生在那! DO为您提供了可以像本地对象一样使用的代理对象(大多数情况下),它们的语法和所有内容都完全相同,只是您的消息飞到另一个进程并在那里执行。 DO通常在马赫端口上运行,但也可以与套接字一起使用,从而使其也可以在计算机之间工作。DO确实是很酷的技术,当人们从诸如Java或C ++之类的次要语言进入Objective-C时,DO往往会引起人们的注意。不幸的是,DO确实又老又脆弱,而且往往异常不可靠。与套接字一起使用它与远程计算机通信时尤其如此,但在本地使用它时甚至如此。 DO也是完全非模块化的,因此基本上不可能交换它用于自定义内容的IPC机制(例如,如果要加密流)。仅了解其工作原理是值得研究的,尽管缺点在某些情况下仍然非常有用。

6、分布式通知:这些是简单的单向消息,本质上会广播到正在监听它们的会话中的任何进程。极易使用,并且有Cocoa和CoreFoundation两种方式。 (并且它们可以互操作!)缺点是它们不能保证交付,并且它们非常占用资源,因为可能会向系统中的每个应用程序发送消息。它们完全不适合将大图传输到另一个过程,但是对于简单的一次性事件(例如“我刚刚更改了偏好,现在重新阅读”)非常有用。在内部,这是通过使用Mach端口与集中式通知服务器进行通信来实现的,该服务器管理将通知发送到他们想去的位置的任务。

7、Pasteboard:可能是您最常使用的IPC机制。每次在应用程序之间复制和粘贴内容时,就会发生IPC!应用程序间拖放操作也使用粘贴板,并且可以创建自定义粘贴板以在应用程序之间来回传递数据。类似于分布式通知,粘贴板通过使用mach端口与中央粘贴板服务器通信来工作。

那么哪一个适合您呢?好吧,这一切都取决于您在做什么。多年来,我几乎都使用这些工具来完成不同的事情。您必须查看哪个最适合您的问题,并且我希望以上内容为您提供一个入门的好地方。

你可能感兴趣的:(进程间的通信)