“共享内存模型”与“消息传递模型”

Posted handler-刘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“共享内存模型”与“消息传递模型”相关的知识,希望对你有一定的参考价值。

共享内存模型概述

在共享内存模型中,应用程序进程会在其本地地址空间中创建一个 RSM 导出段。一个或多个远程应用程序进程创建 RSM 导入段,在导出段与导入段之间建立互连的虚拟连接。所有进程将使用其特定地址空间的本地地址,来实现对共享段的内存引用。

应用程序进程通过为 RSM 导出段分配可在本地寻址的内存来创建此导出段。使用标准 Solaris 接口(如 System V 共享内存、mmap(2) 或 valloc(3C))之一即可实现此分配。然后,进程会调用 RSMAPI 来创建段,用于为已分配的内存提供引用句柄。RSM 段通过一个或多个互连控制器进行发布。可以远程访问已发布的段。另外,还将发布允许导入该段的节点的访问特权列表。

将为导出的段分配一个段 ID。通过该段 ID 及其创建进程的群集节点 ID,导入进程可唯一地指定一个导出段。如果成功创建了导出段,则会向进程返回一个段句柄,以便在后续段操作中使用。

应用程序进程通过使用 RSMAPI 来创建导入段,便可以对已发布的段进行访问。创建导入段之后,应用程序进程便建立了互连的虚拟连接。如果成功创建此导入段,则会向应用程序进程返回一个 RSM 导入段句柄,以便在后续段导入操作中使用。建立虚拟连接之后,如果互连支持内存映射,则应用程序可能会请求 RSMAPI 提供内存映射以进行本地访问。如果不支持内存映射,则应用程序可以使用 RSMAPI 提供的内存访问原语。

RSMAPI 提供了一种机制,该机制可以支持远程访问错误检测并能解决写入顺序内存模型问题。此机制称为屏障

RSMAPI 提供一种通知机制,可以同步本地访问和远程访问。当导入进程完成数据写入操作后,导出进程便可以调用函数使自身阻塞。当导入进程完成写入后,此进程会通过调用信号函数来使导出进程解除阻塞。解除阻塞之后,导出进程便可以处理数据。

引文:共享内存模型概述 - 编程接口指南

1、共享内存这种方式比较常见,我们经常会设置一个共享变量。然后多个线程去操作同一个共享变量。从而达到线程通讯的目的。例如,我们使用多个线程去执行页面抓取任务,我们可以使用一个共享变量count来记录任务完成的数量。每当一个线程完成抓取任务,会在原来的count上执行加1操作。这样每个线程都可以通过获取这个count变量来获得当前任务的完成情况。当然必须要考虑的是共享变量的同步问题,这也共享内存容易出错的原因所在。

 这种通讯模型中,不同的线程之间是没有直接联系的。都是通过共享变量这个“中间人”来进行交互。而这个“中间人”必要情况下还需被保护在临界区内(加锁或同步)。由此可见,一旦共享变量变得多起来,并且涉及到多种不同线程对象的交互,这种管理会变得非常复杂,极容易出现死锁等问题。

  • 共享内存型Shared Memory
    • 线程Threads
    • 锁Locks
    • 互斥l量Mutexes

 

消息传递模型

1、消息传递方式采取的是线程之间的直接通信,不同的线程之间通过显式的发送消息来达到交互目的。消息传递最有名的方式应该是actor模型了。在这种模型下,一切都是actor,所有的actor之间的通信都必须通过传递消息才能达到。每个actor都有一个收件箱(消息队列)用来保存收到其他actor传递来的消息。actor自己也可以给自己发送消息。这才是面向对象的精髓啊!

这种模型看起来比共享内存模型要复杂。但是一旦碰到复杂业务的话,actor模型的优势就体现出来了。我们还是以刚才多线程抓取网站为例子看一下在这种模型下如何去解决。

首先我们定义一个统计actor用来统计任务完成量。然后把多个网址(消息方式)发给多个抓取actor,抓取actor处理完任务后发送消息通知统计actor任务完成,统计actor对自己保存的变量count(这个只有统计actor才能看到)加一。

最后让我们来总结一下这两种通讯模式:

并发模型通信机制同步机制
共享内存

线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信。

同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。

消息传递(actor)

线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信。

由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。

       在信息传递模型中,不同的通信核心层不会共享同一个内存空间。由于大部分现流行的处理器的指令集架构缺乏本机扩展程序,用以提供在指令层中传递信息的基元,所以一般情况下,信息传递通常需要需要大量的系统开销。正因为这些系统开销,通常信息的传递无法频繁的进行,还是需要通过共享内存的方式来实现处理器之间的批量数据传送

  • 消息传送型(CSP和Actor模型)
    • 进程Processes
    • 消息Messages
    • 不共享数据(状态)No shared data

CSP和Actor模型基本特性对比

Actor

  1. 基于消息传递message-passing
  2. 消息和信箱机制:消息异步发送
  3. 保留可变状态但不共享
  4. 失败检测和任其崩溃
  5. 重点在于发送消息时的实体

CSP

  1. 基于消息传递message-passing
  2. 顺序进程Sequential processes
  3. 通过channel同步通信Synchronous communication through channels
  4. 频道交替复用Multiplexing of channels with alternation
  5. 重点在于发送消息时使用的通道channel

 引文:基于消息传递的并发模型 - 知乎

参考资料:

并发模型之——共享内存模型(线程与锁)理论篇 - AiFly - 博客园

共享内存和消息传递_愿世界和平的IT劝退师-CSDN博客_消息传递

共享内存和消息传递 - 简书

共享内存和消息队列原理概述 - Smah - 博客园

golang(go语言)消息传递(管道)方法实现发送多个get请求_拼命小李博客-CSDN博客

Golang之消息机制channel_NNnora的博客-CSDN博客

[golang] nats的消息传递模型介绍 - 靑い空゛ - 博客园

以上是关于“共享内存模型”与“消息传递模型”的主要内容,如果未能解决你的问题,请参考以下文章

并发模型与IO模型梳理

Java并发编程-- Java内存模型

Linux编程之共享内存

Java内存模型

Java内存模型

Linux编程入门一POSIX共享内存