Erlang 并发编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Erlang 并发编程相关的知识,希望对你有一定的参考价值。

Erlang 并发编程

编写并发程序很简单,只需要三个基本函数:spawn、send 和 receive。spawn 创建一个并行进程,send 向某个进程发送消息,receive 则是接收消息。

Erlang 的并发是基于进程的,进程是一些独立的小型虚拟机,可以执行 Erlang 函数。在 Erlang 里,进程隶属于编程语言,而非操作系统。这就意味着 Erlang 的进程在任何操作系统上都会具有相同的逻辑行为,这样就可以编写可移植的并发代码。

并发函数

  • Pid = spawn(Mod, Func, Args)

创建一个新的并发进程来执行 apply(mod, Func, Args)。这个新进程和调用进程并列运行。spawn 返回一个 Pid。可以用 Pid 来给此进程发送消息。注意:元数为 length(Args) 的 Func 函数必须从 Mod 模块导出。当一个新进程被创建后,会使用最新版的代码定义模块。

  • Pid = spawn(Fun)

创建一个新的并发进程来执行 Fun()。这种形式的 spawn 总是使用被执行 fun 的当前值,而且这个 fun 无需从模块里导出。

  • Pid ! Message

向标识符为 Pid 的进程发送消息 Message。消息发送是异步的。发送方并不等待,而是会继续之前的工作。! 被称为发送标识符。Pid ! M 被定义为 M。因此 Pid1 ! Pid2 !...! Msg 的意思是把消息 Msg 发送给 Pid1、Pid2 等所有进程。

  • receive ... end

接受发送给某个进程的消息。语法如下:

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。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

以上是关于Erlang 并发编程的主要内容,如果未能解决你的问题,请参考以下文章

1.Erlang/OTP平台

Erlang 并发编程基础之一

回顾Erlang简要

Erlang / OTP并发编程实战 Erlang程序设计.第2版 PDF分享

Erlang 摘要

如何等待用户的输入并继续进行erlang并发编程中的进一步代码?