UNIX域套接字与共享内存(映射文件)

时间:2010-01-20 13:36:44

标签: unix memory sockets

有人能说,与共享内存(或备用内存映射文件)相比,UNIX域套接字有多慢?

感谢。

5 个答案:

答案 0 :(得分:66)

这更像是一个设计问题,而不是速度(共享内存 更快),域套接字明显更具UNIX风格,并且可以解决更少的问题。在事先知道的选择方面:

域套接字优势

  • 阻止和非阻塞模式以及它们之间的切换
  • 任务完成后你不必释放它们

域套接字缺点

  • 必须以线性方式阅读和书写

共享内存优势

  • 非线性存储
  • 永远不会阻止
  • 多个程序可以访问它

共享内存不利

  • 需要锁定实施
  • 需要手动释放,即使未被任何程序使用

这就是我现在所能想到的。但是,我每天都会使用域套接字 - 更不用说重新实现它们来分布式计算要容易得多。由于需要安全设计,共享内存的速度增益将会丢失。但是,如果您确切知道自己在做什么,并使用正确的内核调用,那么可以通过共享内存实现更快的速度。

答案 1 :(得分:10)

在速度方面,共享内存绝对是赢家。使用套接字,您将拥有至少两个数据副本 - 从发送进程到内核缓冲区,然后从内核到接收进程。对于共享内存,延迟仅受到盒子核心之间的缓存一致性算法的约束。

正如Kornel所指出的那样,处理共享内存更加复杂,因为你必须提出自己的同步/信令方案,这可能会增加延迟,具体取决于你走的路线。绝对在共享内存中使用信号量(在Linux上用futex实现),以避免在非竞争情况下进行系统调用。

答案 2 :(得分:4)

两者都是进程间通信(IPC)机制。 UNIX域套接字用于一个主机上的进程之间的通信,类似于在不同主机之间使用TCP套接字。 共享内存(SHM)是一块内存,您可以在其中放置数据并在进程之间共享。 SHM通过使用指针为您提供随机访问,可以写入或读取套接字,但您无法倒带或进行定位。

答案 3 :(得分:0)

在这种情况下 - 套接字更快。写入共享内存比任何IPC都要快,但是写入内存映射文件并写入共享内存是完全不同的事情。

当写入内存映射文件时,您需要将写入共享内存的内容“刷新”到实际的绑定文件(不完全是,正在为您完成刷新),因此您首先将数据复制到共享内存,然后你再次复制(刷新)到实际文件,这是超级duper扩展 - 甚至更多,甚至更多,然后写入套接字,你没有做到这一点。

答案 4 :(得分:0)

@Kornel Kisielewicz 的回答是很好的 IMO。只是在这里添加我自己的套接字结果,而不仅仅是 Unix 域套接字。

共享内存

  • 性能非常高。没有带有 RAW 访问数据的副本。访问速度肯定是最快的。
  • 需要同步。对于复杂的情况,设计并不那么容易设置。
  • 固定大小。 Growing shared memory is doable 但内存必须先取消映射,增长,然后重新映射。
  • 信令机制可能很慢,请参见此处:Boost.Interprocess notify() performance。特别是如果您想在进程之间进行大量交换。信令机制也不太容易设置。

套接字

  • 易于设置。
  • 可以在不同的机器上使用。
  • 无需复杂的同步。
  • 如果您使用 TCP,大小不是问题。简单的设计,头部包含数据包大小,然后发送数据。
  • Ping/Pong 交换速度很快,因为它可以被操作系统视为硬件中断。
  • 性能一般:只制作了几份数据。
  • 与共享内存相比,CPU 消耗较高。如果您经常使用套接字调用,则它们并不便宜。

在我的测试中,小块数据的交换(大约 1MB/秒)显示共享内存没有真正的优势。我什至会说使用 TCP 的 ping/pong 交换速度更快(由于简单有效的信号机制)。 但是在交换大量数据(大约 200 兆字节/秒)时,我使用套接字的 CPU 消耗为 20%,而使用共享内存的 CPU 消耗为 3%。因此,共享内存在 CPU 方面取得了巨大的胜利,因为 readwrite 套接字调用并不便宜。