erlang 并发编程

原创
2015/05/31 13:54
阅读数 158

1.基本并发函数                

    Pid = spawn(Mod, Fuc, Args)

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

     Pid = spawn(Fun).

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

    这两种spawn形式的本质区别与动态代码升级有关。

    Pid ! Message

    向标识符为Pid的进程发送消息Message。 消息发送是异步的。 发送方并不等待,而是会继续之前的工作。 !被称为发送操作符。

    Pid1!Pid2!Pid3! ... !Msg 的意思是把消息Msg发送给Pid1, Pid2等所有进程。

    recevie ... end

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

receive 
       Pattern1   [when Guard1] ->
                     Expressions1;
       Pattern2   [when Guard2] ->
                    Expressions2;
       ...
end

  当某个消息到达进程后,系统会尝试将它与pattern1(以及可选的关卡Guard1)匹配,如果成功就执行Expressions1。 如果第一个模式不匹配,就会尝试pattern2, 以此类推。

   如果没有匹配的模式,消息会被保存起来以供以后处理,进程则会开始等待下一条消息。

当spawn命令被执行时,系统会创建一个新的进程。每个进程都带有一个邮箱,这个邮箱是和进程同步创建的。

给某个进程发送消息后,消息会被放入该进程的邮箱。只有当程序执行一条接收语句时才会读取邮箱。



例子:

-module(area_server_final).
-export([start/0, area/2, loop/0]).

start() -> spawn(area_server_final, loop, []).

area(Pid, What) ->
    rpc(Pid, What).
rpc(Pid, Request) ->
   Pid ! {self(), Request},
   receive
       {Pid, Response} ->
           Response
   end.

loop() ->
    receive
        {From, {rectangle, Width, Ht}} ->
              From ! {self(), Width*Ht},
              loop();
        {From, {circle, R}} ->
             From ! {self(), 3.141596*R*R},
             loop();
       {From, Other} ->
             From ! {self(), {error, Other}},
             loop()
    end.

执行结果如下:



2 :注册进程

     如果想给一个进程发送消息,就需要知道它的PID, 但是当进程创建时,只有父进程才知道它的PID。系统里没有其他进程知道它的存在。这通常很不方便,因为你必须把PID发送给系统里所有想要和它通信的进程。另一方面,这也是很安全的。如果不透露某个进程的PID,其他进程就无法以任何方式与其交互。

    Erlang有一种公布进程标识符的方法,它让系统里的任何进程都能与该进程通信。这样的进程被称为注册进程(registered process)。管理注册进程的内置函数有四个。

  •  register(AnAtom, Pid)

    用AnAtom(一个原子)作为名称来注册进程Pid 。如果AnAtom 已被用于注册某个进程,这次注册就会失败。

  • unregister(AnAtom)

    移除与AnAtom关联的所有注册消息。

    注意: 如果某个注册进程崩溃了,就会自动取消注册。

  • whereis(AnAtom) -> Pid | undefined

    检查AnAtom是否已被注册。如果是就返回进程标识符Pid, 如果没有找到与AnAtom关联的进程就返回原子undefined.

  • registered() -> [AnAtom:atom()]

    返回一个包含系统所有注册进程的列表。


例子: 用register 来制作一个模拟时钟的注册进程。

-module(clock).
-export([start/2, stop/0]).

start(Time, Fun) ->
    register(clock, spawn(fun() -> tick(Time, Fun) end)).

stop() -> clock ! stop.

tick(Time, Fun) ->
    receive
        stop ->
             void
    after  Time ->
           Fun(),
           tick(Time, Fun)
    end.

这个时钟不断滴答作响,直到你停止它。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部