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

SyB*_*Ber 45 unix sockets memory

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

谢谢.

Kor*_*icz 68

这是更多的设计的问题,比速度(共享内存更快),域套接字是更明确的UNIX风格,做少了很多的问题.在事先知道的选择方面:

域套接字的优点

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

域套接字缺点

  • 必须以线性方式读写

共享内存优势

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

共享内存的缺点

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

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

  • `需要手动释放,即使未被任何程序使用'也可以与[`/dev/ashmem`](http://lwn.net/Articles/452035/)进行斗争 (2认同)

Nik*_*sov 12

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

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


pou*_*ill 8

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

共享内存

  • 性能非常高。没有包含 RAW 访问数据的副本。肯定是最快的访问。
  • 需要同步。对于复杂的情况,设计不太容易设置。
  • 固定尺寸。增加共享内存是可行的,但必须首先取消映射内存,增加内存,然后重新映射。
  • 信令机制可能非常慢,请参见此处:Boost.Interprocess notification() 性能。特别是如果您想在进程之间进行大量交换。信令机制也不太容易设置。

插座

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

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


sta*_*ker 6

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