Concurrency 并发Erlang码

Concurrency 并发Erlang码,concurrency,erlang,Concurrency,Erlang,从一个旧的考试中,有一个问题我不明白答案。该问题的模块如下所示: -module(p4). -export([start/0, init/0, f1/1, f2/1, f3/2]). start() -> spawn(fun() -> init() end). init() -> loop(0). loop(N) -> receive {f1, Pid} -> Pid ! {f1r, self(), N

从一个旧的考试中,有一个问题我不明白答案。该问题的模块如下所示:

-module(p4).
-export([start/0, init/0, f1/1, f2/1, f3/2]).

start() ->
    spawn(fun() -> init() end).

init() ->  loop(0).

loop(N) ->
    receive
        {f1, Pid} ->
            Pid ! {f1r, self(), N},
            loop(N);
        {f2, Pid} ->
            Pid ! {f2r, self()},
            loop(N+1);
        {f3, Pid, M} ->
            Pid ! {f3r, self()},
            loop(M)
    end.

f1(Serv) ->
    Serv ! {f1, self()},
    receive {f1r, Serv, N} -> N end.

f2(Serv) ->
    Serv ! {f2, self()},
    receive {f2r, Serv} -> ok end.

f3(Serv, N) ->
    Serv ! {f3, self(), N},
    receive {f3r, Serv} -> ok end.
问题要求考虑以下函数作为代码的一部分,以及函数的结果将是什么。正确答案是2。我认为应该是3,因为“增加调用”
f2(服务器)
是在
self()的响应之后!{f1r,服务器,2}

    test3() ->
      Server = start(),
      self()!{f1r, Server, 2},
      f2(Server),
      f1(Server).
我的问题是:

  • 为什么答案是2而不是3,以及
    self()是如何做的!{f1r,服务器,2}
    工作吗
  • 是不是
    self()!{f1r,Server,2}
    函数的
    f1(Serv)
    循环(N)中的receive子句的响应
    • self()!{f1r,Server,2}
      {f1r,Server,2}
      发送到自身。 此邮件将在收件箱中等待,直到收到

      然后执行
      f2
      ,然后执行
      f1

      在最后一个函数中,当执行最后一行
      receive{f1r,Serv,N}->N end
      时,运行
      test3
      的进程接收收件箱中等待的消息(发送到自身的消息)并返回该消息中的2


      请注意,在程序结束时,收件箱中将有一个
      {f1r,N}
      等待,N的值为1

      那么,循环函数中的receive子句接收
      Serv!是否正确!{f1,self()}
      来自最后的
      f1(Server)
      调用,但是它没有发回
      {f1r,Server,1}
      ,而是发回队列
      {f1r,self(),2}
      ?不,它也发送
      {f1r,Server,1}
      ,但是,在接收时,它首先接收
      {f1r,Server,2}
      ,因为它已经排队了。
      {f1r,Server,1}
      将在收件箱中等待接收。但是,代码示例永远不会收到它。