An object oriented language is a language with good support for objects.
A concurrency oriented language has good support for concurrency.
--Joe Armstrong
两类通用并发模型:参考七周七并发模型git
共享内存型Shared Memory程序员
消息传送型(CSP和Actor模型)github
重点介绍消息传送型的两种模型Actor和CSP(Communicating Sequential Process)的各项对比shell
主要目的:除了经常使用的Python、Java等用的并发模型以外,还存在这么个东西数据库
先看两段代码缓存
使用Erlang代码和Go代码分别实现打印服务print_server,用来对比模型使用差别并发
Actor模型-Erlang代码异步
%%%------------------------------------------------------------------- %%% @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输出结果以下:ide
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消息
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) }
输出结果以下:
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
CSP
Actor
Actor1等待消息并阻塞,直到Actor2发送消息给Actor1
Actor2发送消息给Actor3,暂存在Actor3的Mailbox中,直到Actor3接受并处理
CSP
Process1读取channel因没有消息阻塞,直到Process2向该channel添加消息
process2向channel添加消息并阻塞,直到Process3读取该channel消息
使用Erlang原语,代码以下:
使用OTP的gen_server,代码以下:
使用Erlang/OTP实现的IP数据库,能够根据IP查询到具体的国家省份等,代码以下:
好比:执行算术异常崩溃
为何没有容量自动增大的缓冲区?
即便如今有一个看上去永不枯竭的资源,总有一天这个资源仍是会被用尽的。多是由于时过境迁,当初的老程序如今须要解决更大规模的问题;也多是存在一个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!
参考:
记得帮我点赞哦!
精心整理了计算机各个方向的从入门、进阶、实战的视频课程和电子书,按照目录合理分类,总能找到你须要的学习资料,还在等什么?快去关注下载吧!!!
念念不忘,必有回响,小伙伴们帮我点个赞吧,很是感谢。
我是职场亮哥,YY高级软件工程师、四年工做经验,拒绝咸鱼争当龙头的斜杠程序员。
听我说,进步多,程序人生一把梭
若是有幸能帮到你,请帮我点个【赞】,给个关注,若是能顺带评论给个鼓励,将不胜感激。
职场亮哥文章列表:更多文章
本人全部文章、回答都与版权保护平台有合做,著做权归职场亮哥全部,未经受权,转载必究!