消息传递和共享内存模型之间的区别是什么?

时间:2012-12-09 19:00:04

标签: concurrency shared-memory message-passing

该问题重复了here问题的主题。

我想就不同的观点要求进一步澄清。

在分布式计算中,最终使用通过网络信道传递的消息,分布式锁定等来实现存储器一致性。消息传递,IIUC,并不总是消除并发性,除非在非常低的级别,因为进程仍然通常影响彼此状态。他们这样做,他们认为是一贯的方式。

例如,可以在消息传递的基础上实现简单的命令解释器,并且可以将命令作为多个远程进程并行执行的多个远程事务的一部分来发送。因此,在大多数情况下,高级别交互需要设计并发性。也就是说,IMO,进程不太可能没有长期操作的事务语义。

此外,发送具有一致状态值的消息并不能保证正确性。重要的是,如何生成此值以及在提供输入数据的消息和发布转换结果的消息之间发生的情况。

另一方面,与物理内存的低级别交互总是基本上是通过总线传递的某种消息。因此,在最低级别,共享内存和消息传递是相同的。

在每个指令级别,通常保证对齐的加载和存储的原子性。所以,这种区别对我来说仍然很模糊。

在散文中,共享内存与消息传递的选择如何与并发相关?是否只是选择解决并发性的技术模式,以及用于定义和分析并行流程交互的数学模型,还是这些技术也是系统应用的架构模式,从根本上影响系统中的并发问题?

感谢。

修改(其他一些备注)

显然,这两种方法的区别在于正确性和性能。但是我对这种区别存在以下问题。

我知道消息可以像大散点虚拟基准的转移一样。但是,除非非单一(或程序生成)逻辑数据的原子读取之外,“按值”方法不保证一致性。通过一致性,我暗示了类似因果关系或顺序排序的变化等等。事实上,通过消息传递,每个进程只会改变自己的内存。进程就像其私有内存的控制器一样。这就像在消息传递之上共享一样,由拥有该数据的进程序列化,但是基于MESSAGE-BY-MESSAGE(类似于内存在逐字或高速缓存行上逐行序列化的方式)基础)。应用程序员仍然有责任保证发送消息所涉及的事务的同步。也就是说,来自多个会话进程的一个进程的消息必须以与这些进程正在执行的操作的语义相对应的一致顺序发送。可能是控制消息到拥有进程,或者通过竞争者之间的直接协调,但是对于消息的并发性的一些限制应该是最有必要的。

对于本地进程间通信(忽略争用),共享内存确实更快,但为什么跨机器通信会出现这种情况?用于分布式计算的共享存储器在网络通信之上实现。因此,除了缓存优势之外,共享内存不能更快。

技术明显不同。我似乎无法理解的是,当任何一个都没有任何本质上有益的东西时,它们如何被广泛地相互比较。必须假设平台提供什么,以及软件试图完成什么,这种假设不可能普遍存在。

1 个答案:

答案 0 :(得分:4)

如果您正在构建分布式和/或多线程应用程序,那么您需要确保它比单个进程单线程应用程序执行得更好。

对于分布式应用程序,即潜在多个系统上的多个进程,通信节点之间的延迟是主要关注点。随着微服务器的出现,延迟和功耗显着降低到软件开发人员开始考虑如何设计,开发,调试,部署等多核/微服务器应用程序的程度。

在开发多进程应用程序时,通常归结为在最低层使用两组OS调用来实现进程间通信:共享内存,例如:通过使用shmget,shmat,shmctl等,以及消息传递,例如,通过使用socket,accept,send,recv等

使用共享内存时,延迟可以忽略不计。一旦获得对共享内存缓冲区的引用,应用程序就可以转到共享内存的任何部分并对其进行修改。当然,进程必须使用锁,互斥锁等进行协作,以确保维护数据结构的完整性并确保应用程序正常工作。此解决方案的问题是,当无法控制何时可能发生上下文切换时,如何测试保持完整性的所有情况?

通过消息传递,不会共享任何数据。所有通信都是通过交换缓冲区。这消除了必须关注锁,互斥锁等,但现在必须确保应用程序可以处理诸如网络超时,带宽,延迟等问题。

为了开发可扩展到单个系统之外的应用程序,最常用的方法是使用消息传递。如果通信进程碰巧在同一主机上,它仍然有效。

无论是共享内存还是消息传递,最终的并发性主要是在共享内存的情况下确保具有锁/互斥锁的数据结构的完整性,以及在消息传递的情况下序列化请求/响应。