erlang学习笔记3-并发
Erlang进程之间没有共享内存,每一个进程都有它自己的内存。想要修改其他进程的内在你只能向它发送一个消息,然后希望它能收到而且能理解这个消息。
创建和销毁进程非常迅速;
在两个进程间收发消息非常迅捷;
进程在所有操作系统上行为相同;
可以创建大量进程;
进程之间不共享任何数据,彼此完全独立;
进程间交互的唯一方法就是通过消息传递。
并发原语:
Pid = spawn(Fun)
创建一个新的并发进程,用于对Fun求值。
Pid ! Message
向标识符为Pid的进程发送消息。消息发送是异步的。
receive ... end
接收一个发送给当前进程的消息。
receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard2] ->
Expressions2;
...
end
客户/服务器架构:
rpc通信
使用erlang:system_info(process_limit)查找系统允许的进程上限。
带超时的receive
receive
Pattern1 [when Guard1] ->
Expressions1;
Pattern2 [when Guard2] ->
Expressions2;
...
after Time ->
Expressions
end
选择性接收:
send 把一个消息发送到一个进程的邮箱中去。同理receive则是在试图把一条消息从进程邮箱中删除。
receive的内部工作机制是:
1、当进入一个receive语句时,我们启动一个计时器(只有表达式中存在after段时才会计时)。
2、从邮箱中取出每个消息,然后尝试进行模式匹配。如果匹配成功,消息就从邮箱中删除,对应的模式之后的表达式就会被求值。
3、如果邮箱中的第一个消息不能匹配receive语句的任何一个模式,那么就会将第一个消息从邮箱中删除并送入一个“保存队列”,然后继续尝试邮箱中的第二个消息。这个过程会不断重复直到找到匹配的消息,或者邮箱中所有的消息全部检查完毕。
4、如果邮箱中所有的消息都不能匹配,那么就挂起进程,直到下一次又有新的消息进入邮箱时再对该进程进行重新调度执行。注意,当一个新消息到达时,只对新消息进行匹配而不会对保存队列中的消息进行再次匹配。
5、一个消息如果被匹配,那么存入保存队列中的所有消息就会按照它们到达进程的时间先后顺序重新放回邮箱中。这时,如果开启了一个计时器,那么这个计时器就会被清空。
6、如果在我们等待一个消息时触发了计时器,那么对表达式ExpressionsTimeout求值然后把存入保存队列中的所有消息按照它们到达进程的时间先后顺序重新放回邮箱中。
注册进程:
register(AnAtom, Pid)
unregister(AnAtom)
whereis(AnAtom) ->Pid | undefined
registered() -> [AnAtom::atom()]
尾递归技术:
erlang中的尾递归的函数可以无限循环而不需要消耗栈空间。
使用MFA启动进程:
以显式指明模块、函数名和参数列表的形式来启动一个新进程。