【Erlang】学习笔记-actor模型

    erlang面向并发编程的,而能够并发的核心就是actor模型,理解actor模型至关重要,当然actor模型并不是erlang所特有的。其他语言和库也有用到,例如:Elixir, Akka (for the JVM) 和 Celluloid (for Ruby)。

    传统的并发实现一般是这样的:多线程或者多进程,多个请求来临时放入共享内存,通过加锁的方式达到正确的处理结果,但是加锁会带来性能上的损耗和调试困难等诸多问题。

Actor模型是怎么实现并发的

    在erlang中,进程是最小的单位,一个进程就是一个actor,erlang进程和系统进程不是一个概念,erlang进程是运行在erlang虚拟机上的轻量级单位,可以瞬间创建上万个,创建一个erlang进程需要300个字的内存空间,创建时间几微秒,每个核启动一个线程充当调度器,每个进程之间不共享内存,依靠互发消息来进行通信,每个进程有自己的进程邮箱,收到的消息都会按顺序放进去再取出处理。一群actor独立运行,彼此之间互发消息,就像是一群叽叽喳喳的人在互相交流,这就是actor模型实现的并发。

一个actor模型收到消息后可以选择做下面三件事的一件:

    1>Create more actors; 创建其他actors

    2>Send messages to other actors; 向其他actors发送消息

    3>Designates what to do with the next message. 指定下一条消息到来的行为

Erlang 中的并发编程使用到的erlang函数。

Pid = spawn(Mod,Func, Args) 
创建一个新的并发进程来执行Mod模块中的 Fun(),Args 是参数。

Pid ! Message 
给进程号为 Pid 的进程发送消息。消息发送是异步的,发送方不等待而是继续之前的工作。

receive… end 
接受发送给某个进程的消息,匹配后处理。

每个actor只能按顺序处理消息,一次只能处理一条,所以如果你要并行处理10条消息,你需要把这条消息发给10个actors。

预防和处理错误

1、定义进程状态:借助递归函数,进程的状态保存到递归函数的参数中

2、隐藏消息实现:使用函数来处理消息的接收和发送

3、超时处理(防止死锁)属于receive语句中的一部分,Delay单位是毫秒,超时后没有收到和Match模式匹配的消息,会执行after部分:

receive 

    Match -> Expression1

after Delay ->

    Expersion2

end.

4.选择性接收:通过嵌套调用对接收到的消息进行优先级排序,但是如果无用的消息太多会导致性能下降

5、邮箱风险的解决:确保有匹配不到的消息的处理,打日志,方便bug调试

多进程中高效的处理错误

1、链接:是两个进程之间的特殊关系,一个进程意外死亡时,与之有链接关系的进程也会死亡,阻止错误蔓延,建立链接函数:link/1,参数是pid,建立当前进程和pid的链接,为防止进程在链接建立成功之前就死亡了,提供了spawn_link函数,把创建进程和建立链接封装成了一个原子操作。

2、重启进程:系统进程可以检查是否有进程死亡并重启死亡进程,process_flag(trap_exit,true)实现erlang进程转系统进程。

3、监控器:特殊的链接,监控器是单向的,两个进程间可设置多个监控器,监控器可以叠加,每个监控器有自己的标识,可以单独的移除,创建监控器:erlang:monitor/2,第一个参数永远是原子process,第二个参数是进程pid。监控进程死活,创建进程同时监控进程:spawn_monitor。

4、给进程命名,方便在进程死亡后重启:erlang:register(Name,Pid)。进程死亡则自动失去名字。

你可能感兴趣的:(Erlang)