前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >基于消息传递的并发模型

基于消息传递的并发模型

作者头像
职场亮哥
发布于 2020-10-10 07:14:57
发布于 2020-10-10 07:14:57
79800
代码可运行
举报
文章被收录于专栏:职场亮哥职场亮哥
运行总次数:0
代码可运行

An object oriented language is a language with good support for objects. A concurrency oriented language has good support for concurrency. --Joe Armstrong

两类通用并发模型:参考七周七并发模型

  • 共享内存型Shared Memory
    • 线程Threads
    • 锁Locks
    • 互斥l量Mutexes
  • 消息传送型(CSP和Actor模型)
    • 进程Processes
    • 消息Messages
    • 不共享数据(状态)No shared data

重点介绍消息传送型的两种模型Actor和CSP(Communicating Sequential Process)的各项对比

主要目的:除了常用的PythonJava等用的并发模型之外,还存在这么个东西

先看两段代码

代码示例对比

使用Erlang代码和Go代码分别实现打印服务print_server,用来对比模型使用差异

Actor模型-Erlang代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
%%%-------------------------------------------------------------------
%%% @author Suncle
%%% @doc
%%% print_server
%%% @end
%%% Created : 2017/12/18 14:53
%%%-------------------------------------------------------------------
-module(print_server).
-author("Flowsnow").

%% API
-export([print_server/0, start_print_server/0, send_msg/2]).


print_server() ->
  receive
    Msg ->
      io:format("print_server received msg: ~p~n", [Msg]),
      print_server()
  end.

start_print_server() ->
  Pid = spawn(?MODULE, print_server, []),
  Pid.

send_msg(Msg, Pid) ->
  Pid ! Msg,
  io:format("send_normal_msg: ~p~n", [Msg]).

Erlang shell输出结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1> c("print_server.erl").
{ok,print_server}
2> Pid = print_server:start_print_server().
<0.39.0>
3> print_server:send_msg("hello", Pid).
send_normal_msg: "hello"
print_server received msg: "hello"
ok

以上print_server使用的是最原始的Erlang语法实现的,也可以使用OTP gen_server原语实现更加清晰易懂

CSP模型-Go代码

print函数从channel读取消息并阻塞,直到主函数向channel写入hello消息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
	"fmt"
	"time"
)

func main() {
	c := make(chan string)
	go print(c)
	time.Sleep(1 * time.Second)
	fmt.Println("main function: start writing msg")
	c <- "hello"

	var input string
	fmt.Scanln(&input)
}

func print(c <-chan string) {
	fmt.Println("print function: start reading")
	fmt.Println("print function: reading: " + <-c)
	time.Sleep(1 * time.Second)
}

输出结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
D:\workspace\Go>go run print_server.go
print function: start reading
main function: start writing msg
print function: reading: hello

模型图对比

Actor

Actor1发送消息到Actor2的邮箱中,邮箱本质是队列,由Actor2消费

CSP

Process1在Channel的写入端添加消息,Process2在channel的读取端读取消息

基本特性对比

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

通信语义对比

Actor

Actor1等待消息并阻塞,直到Actor2发送消息给Actor1 Actor2发送消息给Actor3,暂存在Actor3的Mailbox中,直到Actor3接受并处理

CSP

Process1读取channel因没有消息阻塞,直到Process2向该channel添加消息 process2向channel添加消息并阻塞,直到Process3读取该channel消息

Erlang实现简易银行账户

使用Erlang原语,代码如下:

使用OTP的gen_server,代码如下:

Erlang小项目:IP数据库

使用Erlang/OTP实现的IP数据库,可以根据IP查询到具体的国家省份等,代码如下:

不一样的Erlang特性

  1. Let it crash思想:值得借鉴

比如:执行算术异常崩溃

  1. 变量是不可变的,变量一旦赋予值就无法再改变:带来的好处就是没有可变状态,就不需要内存共享,也就不需要有锁
  2. Erlang进程之间的唯一交互方式就是消息传递:Erlang中没有像C++那样,进程间拥有多种不同的交互方式(管道、消息队列、存储共享等等)。

FAQ

为什么没有容量自动增大的缓冲区?

即使现在有一个看上去永不枯竭的资源,总有一天这个资源还是会被用尽的。可能是因为时过境迁,当初的老程序现在需要解决更大规模的问题;也可能是存在一个bug,消息没有被及时处理,导致被堆积。如果没有思考缓冲区塞满时的对策,那么在未来的某个时间就有可能出现一个破坏性极强,隐蔽性极深且难以诊断的bug。最好的策略是在现在就思考如何处理缓存区被塞满的情况,将问题消灭在萌芽阶段。 因此常用的缓存区类型有三种:阻塞型(blocking),弃用新值型(dropping),移出旧值型(sliding)

Python有什么消息传递并发模型?

Actor模型pykka:https://github.com/jodal/pykka CSP模型pycsp:https://github.com/runefriborg/pycsp/wiki/Getting_Started_With_PyCSP

图片均来源于here

参考:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。
LhWorld哥陪你聊算法
2018/09/13
7590
Erlang设计原则Behaviour
ChildSpec参数{Id, StartFunc, Restart, Shutdown, Type, Modules}
职场亮哥
2020/10/10
7730
论软件开发中的并行与并发
并发与并行是计算机科学中处理多任务执行的核心概念。并发关注任务的协调与交错执行,而并行则强调任务的真正同时执行,以提升计算效率。尽管这两个术语常被混用,但它们代表了不同的任务执行方式。
AI.NET 极客圈
2025/04/06
860
论软件开发中的并行与并发
【swoole4.0】实现Actor并发模型
Actor概念来源于Erlang, 对于PHPer来说,可能会比较陌生,写过Java的同学会比较熟悉,Java一直都有线程的概念(虽然PHP有Pthread,但不普及),它是一种非共享内存的并发模型,每个Actor内的数据独立存在,Actor之间通过消息传递的形式进行交互调度,且Actor是一种高度抽象化的编程模型,非常适合于游戏、硬件行业。
桶哥
2019/06/14
7830
Actor 分布式并行计算模型: The Actor Model for Concurrent Computation
The Actor Model for Concurrent Computation
一个会写诗的程序员
2021/12/20
2.1K0
Actor 分布式并行计算模型: The Actor Model for Concurrent Computation
分布式计算模式之Actor,助你彻底搞定分布式计算技术
我在前两篇文章中,带你一起学习了 MapReduce 和 Stream 计算模式,(分布式计算技术MapReduce 详细解读,分布式计算技术之流计算Stream,打通实时数据处理)相信你对批处理和流计算也有了一定的了解。虽然这两种计算模式对数据的处理方式不同,但都是以特定数据类型(分别对应静态数据和动态数据)作为计算维度。
架构师修炼
2020/07/20
2.4K0
分布式计算模式之Actor,助你彻底搞定分布式计算技术
scala快速入门系列【Actor并发编程】
本篇作为scala快速入门系列的第三十八篇博客,为大家带来的是关于Actor并发编程的内容。
大数据梦想家
2021/01/26
5590
scala快速入门系列【Actor并发编程】
上帝说:要有一门面向未来的语言,于是有了 erlang
今个谈谈 erlang。 这些文章流于表面,更多是简单的介绍。这篇文章不同,因为 erlang 并不是一门新语言,简单介绍它的人不算少,我希望这篇文章能在深度上有所区别。写文章,雅俗共赏是件困难的事情:讲深了,初学者或者外行读着扫兴;说浅了,专家们会觉着浪费时间。所以,我会尽量做到深入浅出。 言归正传。erlang 是约三十年前上帝馈赠给人间的一份礼物。它是如此独特,在构建的过程中揉进了如此多的奇思妙想,在三十年前就试图解决三十年后我们才大规模遇见的问题,在编程语言史上可算是一个自成体系的标杆。要在一篇文章
tyrchen
2018/03/29
1.4K0
上帝说:要有一门面向未来的语言,于是有了 erlang
并发模型比较
Golang 的特色之一就是 goroutine ,使得程序员进行并发编程更加方便,适合用来进行服务器编程。作为后端开发工程师,有必要了解并发编程面临的场景和常见的解决方案。一般情况下,是怎样做高并发的编程呢?有那些经典的模型呢?
Java知音
2018/09/21
2.1K0
并发模型比较
Erlang服务器占用内存偏高的解决方法
问题提出:Erlang服务器100万人在线,16G内存快被吃光。玩家进程占用内存偏高。
星哥玩云
2022/07/04
6.1K0
Go 并发实战--协程浅析 二
继续上一篇的内容,我们介绍了go协程的实现中的几个核心的对象,也说了他们之间是如何合作工作的。
邹志全
2019/07/31
3180
软件架构:探讨消息传递并发模型的数据安全性
在并发编程领域,正确管理数据共享和同步是开发高效、稳定和安全应用程序的重要组成部分。传统的共享内存并发模型虽然直观,但容易引发数据竞争、死锁等多种问题,增加了开发的复杂性和出错的风险。相比之下,消息传递并发模型以其独特的数据安全性优势,为解决这些并发问题提供了一种有效的替代方案。本文将深入探讨消息传递模型如何保证数据的安全性,以及这种方法在现代软件开发中的应用价值。
运维开发王义杰
2024/05/10
1410
软件架构:探讨消息传递并发模型的数据安全性
三分钟掌握Actor和CSP模型
前文传送门:《三分钟掌握共享内存模型和 Actor模型》, 一直想比较Actor模型与golang的CSP模型,经过一段时间的实战记录了本文。
有态度的马甲
2022/03/30
5640
三分钟掌握Actor和CSP模型
GoLang并发控制(上)
首先解释golang中的channel:channel是go中的核心部分之一,结构体简单概括就是一个ring队列+一个锁 有兴趣的同学可以去研究一下源码构建。在使用中可以将channel看做管道,通过channel迸发执行的go程之间就可以发送或者接受数据,从而对并发逻辑进行控制。
李海彬
2018/12/14
1.4K0
Actor模型和CSP模型的区别
  Akka/Erlang的actor模型与Go语言的协程Goroutine与通道Channel代表的CSP(Communicating Sequential Processes)模型有什么区别呢?
物流IT圈
2019/07/16
1.7K0
Actor模型和CSP模型的区别
从并发模型看 Go 的语言设计
传统的程序语言设计都不会将输入输出作为语言的核心,但 Tony Hoare 认为输入输出是基本的编程原语,且通信顺序进程(Communicating sequential processes,CSP)的并行组合(这里可能用「并发」会更为准确)是基本的程序组织方法。Go 语言的并发设计就是基于 CSP 模型的。
腾讯技术工程官方号
2019/05/16
8440
从并发模型看 Go 的语言设计
Operating System 13 - 并发编程范式
并发编程的源头是在于内存中的数据需要在不同的线程之间共享, 因为多线程程序在运行时存在交错(interleaving).
Reck Zhang
2021/08/11
5770
Operating System 13 - 并发编程范式
并发模型的一些概念以及设计探讨
文章比较长,需要一些耐心才能看完 并发模型简介 并发:一个人同一时间应对多件事的能力 并行:一个人同一时间处理多件事的能力(显然一个人同一事件不能处理多件事,单核CPU不具备并行能力) 可以理解为并行是并发的一种特殊情况 并发模型的核心是为了提高提高CPU利用率,提高服务器应对大量请求,海量数据处理的能力,单核CPU性能已经难以发展,各大厂商都在通过增加CPU个数来达到硬件处理能力的提高(摩尔定律),随之而来在编程语言方面衍生出各个模型(其实就是处理问题的思路)用来压榨硬件的性能,以使自己的系统并发能力得到
阿伟
2019/08/20
7480
PHP物联网开发利器之Actor并发模型
在传统的思维中,经常会有人告诉你,php不适合用来做物联网服务端,让你换java,node,go等其他语言,是的,没错传统意义上的php,确实很难做物联网服务器,因为它实在太蹩脚了,当然,这也不是意味着彻底就不能做。举个例子,当你想实现一个TCP服务器的时候,你可能需要写出原理大约如下的代码:
猿哥
2019/06/14
2.3K1
基于RabbitMQ的异步消息传递:发送与消费
RabbitMQ是一个流行的开源消息代理,用于在分布式系统中实现异步消息传递。它基于Erlang语言编写,具有高可用性和可伸缩性。在本文中,我们将探讨如何在Python中使用RabbitMQ进行消息发送和消费。
用户3578099
2024/07/04
3820
基于RabbitMQ的异步消息传递:发送与消费
相关推荐
【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验