标签:
编写并发程序很简单,只需要三个基本函数:spawn、send 和 receive。spawn 创建一个并行进程,send 向某个进程发送消息,receive 则是接收消息。
Erlang 的并发是基于进程的,进程是一些独立的小型虚拟机,可以执行 Erlang 函数。在 Erlang 里,进程隶属于编程语言,而非操作系统。这就意味着 Erlang 的进程在任何操作系统上都会具有相同的逻辑行为,这样就可以编写可移植的并发代码。
创建一个新的并发进程来执行 apply(mod, Func, Args)。这个新进程和调用进程并列运行。spawn 返回一个 Pid。可以用 Pid 来给此进程发送消息。注意:元数为 length(Args) 的 Func 函数必须从 Mod 模块导出。当一个新进程被创建后,会使用最新版的代码定义模块。
创建一个新的并发进程来执行 Fun()。这种形式的 spawn 总是使用被执行 fun 的当前值,而且这个 fun 无需从模块里导出。
向标识符为 Pid 的进程发送消息 Message。消息发送是异步的。发送方并不等待,而是会继续之前的工作。! 被称为发送标识符。Pid ! M 被定义为 M。因此 Pid1 ! Pid2 !...! Msg 的意思是把消息 Msg 发送给 Pid1、Pid2 等所有进程。
接受发送给某个进程的消息。语法如下:
receive Pattern1 [when Guard1] -> Expressions1; Pattern2 [when Guard2] -> Expressions2; ... end
当某个消息到达进程后,系统会尝试将它与 Pattern1(以及可选的关卡 Guard1)匹配,如果成功就执行 Expressions1。如果第一个模式不匹配,就会尝试 Pattern2,以此类推。如果没有匹配的模式,消息就会被保存起来供以后处理,进程则会开始等待下一条消息。
当 spawn 命令被执行时,系统会创建一个新的进程。每个进程都带有一个邮箱,这个邮箱是和进程同步创建的。给某个进程发送消息后,消息会被放入该进程的邮箱。只有当程序执行一条接收语句时才会读取邮箱。
现在我们创建一个实例,创建一个名为 area_server0.erl 的模块。内部包含计算长方形和圆形面积的函数。
% filename: area_server0.erl -module(area_server0). -export([loop/0]). loop() -> receive {rectangle, Width, Ht} -> io:format("Area of rectangle is ~p~n",[Width * Ht]), loop(); {square, Side} -> io:format("Area of square is ~p~n",[Side * Side]), loop() end.
然后在 shell 里创建一个执行 loop/0 的进程。
$ erlc area_server0.erl $ erl Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] Eshell V6.4 (abort with ^G) 1> Pid = spawn(area_server0, loop, []). <0.35.0> 2> Pid ! {rectangle, 6, 10}. Area of rectangle is 60 {rectangle,6,10} 3> Pid ! {square, 12}. Area of square is 144 {square,12}
spawn(area_server0, loop, []) 会创建一个执行 area_server:loop() 的并行进程,然后返回 Pid,也就是打印出来的 <0.35.0>。
Pid ! {rectangle, 6, 10} 会向 Pid 发送一条 {rectangle, 6, 10} 的消息,这个消息匹配 loop/0 接受语句里的第一个模式:
loop() -> receive {rectangle, Width, Ht} -> io:format("Area of rectangle is ~p~n",[Width * Ht]), loop() ...
接受到消息后,这个进程打印出矩形的面积。最后,shell 打印出 {rectangle, 6, 10} 这是因为 Pid ! Msg 的值被定义为 Msg。
标签:
原文地址:http://www.cnblogs.com/mydevops/p/5216213.html