【发布时间】:2010-02-18 10:51:57
【问题描述】:
我阅读了很多关于消息队列和共享内存之间差异的文章。 但仍不清楚哪一个有利于获得良好的性能。
就像共享内存一样,被认为优于队列,但在同步的情况下也存在性能问题。
【问题讨论】:
-
不是骗人的。一个是关于管道的,一个是关于 shm 的。
标签: operating-system
我阅读了很多关于消息队列和共享内存之间差异的文章。 但仍不清楚哪一个有利于获得良好的性能。
就像共享内存一样,被认为优于队列,但在同步的情况下也存在性能问题。
【问题讨论】:
标签: operating-system
共享内存和消息队列都可以用来在进程之间交换信息。区别在于如何使用它们。
共享内存正是您所想的:它是一个可以由多个进程读写的存储区域。它不提供固有的同步;换句话说,由程序员来确保一个进程不会破坏另一个进程的数据。但它在吞吐量方面是高效的:读取和写入是相对较快的操作。
消息队列是单向管道:一个进程写入队列,另一个进程按照写入顺序读取数据,直到出现数据结束情况。创建队列时,会设置消息大小(每条消息的字节数,通常相当小)和队列长度(待处理消息的最大数量)。访问比共享内存慢,因为每个读/写操作通常是一条消息。但是队列保证每个操作要么成功处理整条消息,要么在不改变队列的情况下失败。所以写者在只写了部分消息后永远不会失败,读者要么会检索到完整的消息,要么什么都没有。
【讨论】:
消息队列具有固有的同步开销,以性能为代价保证安全。 共享内存没有保障——如果两个线程同时访问它,除非您自己确保线程安全,否则它们可能会发生冲突(写入不一致的数据)。 如果允许出现小错误(例如,数据进入模拟输出并且一些噪声是可以接受的),这可能是微不足道的,因此您可以完全跳过错误检查,并以相当高的性能增益采用“足够好”的方法。此外,共享内存允许交换大块数据以及对多个应用程序通用的数据进行通用和持久存储,从而节省内存存储。消息队列用于降低吞吐量 - 例如,您可以利用它们来保护对共享内存的访问。
【讨论】:
在使用共享内存时要考虑可能的竞争条件,即一个进程写入它而另一个进程读取它,请牢记这一点。使用前者存在相关风险,假设有两个进程正在使用它,一个向它写入,另一个从它读取,正在写入的一个因异常情况而死,读取它的进程可能会挂起或崩溃。
共享内存可以被认为比队列更快(低开销,大量数据传递)。但另一方面,队列需要高开销(使队列永久化等的设置)和低数据量。
共享内存的责任是您必须实现同步才能保证线程安全。看看Beej 在 IPC 上的精彩文章。
当使用队列时,它们是线程安全的,而且不仅如此,无论结果如何,消息都保存在队列中,假设两个进程正在使用队列,当一个进程写入它时(以消息的形式) 并且即将从中读取的其他进程在这种情况下由于崩溃或异常情况而死亡或被杀死,该消息仍然存在,如果重新启动,其他进程可以从队列中读取,即没有数据丢失。
这就是两者的区别。
【讨论】:
消息队列和共享内存用于在 2 个进程之间共享数据。 消息队列需要以特定格式共享数据。两个进程必须就此达成一致并共享消息。内核允许我们读取整个消息或不读取消息队列。 但是共享内存需要部分段在两个进程之间共享,两者都可以做一些同步技术并在进程之间共享数据。 由于不需要复制数据共享给其他进程,共享内存更快。
【讨论】: