Process 一个进程可以有两个接收块吗

Process 一个进程可以有两个接收块吗,process,erlang,Process,Erlang,我的工作环境是Erlang。 具有两个不同功能的进程能否在不同功能中具有两个接收块 receive .... end. request() PID!(message) %% Can i get the reply back here instead of the receive block above? 当然可以 使用发送运算符(!)接收发送到进程的消息。这个 模式按顺序与中的第一条消息匹配 邮箱中的时间顺序,然后是第二个,依此类推。如果一场比赛 成功,并且可选的保护序列GuardSeq为t

我的工作环境是Erlang。 具有两个不同功能的进程能否在不同功能中具有两个接收块

receive
....
end.

request()
PID!(message)
%% Can i get the reply back here instead of the receive block above?
当然可以

使用发送运算符(!)接收发送到进程的消息。这个 模式按顺序与中的第一条消息匹配 邮箱中的时间顺序,然后是第二个,依此类推。如果一场比赛 成功,并且可选的保护序列GuardSeq为true,则 对相应的主体进行了评价。匹配的消息已被使用, 将从邮箱中删除,而 邮箱保持不变

以下代码来自
rabbitmq
项目的
supervisor2.erl
。它甚至使用嵌套的
receive
语句。我已经在下面标记了嵌套的
receive

terminate_simple_children(Child, Dynamics, SupName) ->
    Pids = dict:fold(fun (Pid, _Args, Pids) ->
                         erlang:monitor(process, Pid),
                         unlink(Pid),
                         exit(Pid, child_exit_reason(Child)),
                         [Pid | Pids]
                     end, [], Dynamics),
    TimeoutMsg = {timeout, make_ref()},
    TRef = timeout_start(Child, TimeoutMsg),
    {Replies, Timedout} =
        lists:foldl(
          fun (_Pid, {Replies, Timedout}) ->
                  {Reply, Timedout1} =
                      receive %% attention here 
                          TimeoutMsg ->
                              Remaining = Pids -- [P || {P, _} <- Replies],
                              [exit(P, kill) || P <- Remaining],
                              receive {'DOWN', _MRef, process, Pid, Reason} -> %%attention here
                                      {{error, Reason}, true}
                              end;
                          {'DOWN', _MRef, process, Pid, Reason} ->
                              {child_res(Child, Reason, Timedout), Timedout};
                          {'EXIT', Pid, Reason} -> 
                              receive {'DOWN', _MRef, process, Pid, _} ->
                                      {{error, Reason}, Timedout}
                              end
                      end,
                  {[{Pid, Reply} | Replies], Timedout1}
          end, {[], false}, Pids),
    timeout_stop(Child, TRef, TimeoutMsg, Timedout),
    ReportError = shutdown_error_reporter(SupName),
    [case Reply of
         {_Pid, ok}         -> ok;
         {Pid,  {error, R}} -> ReportError(R, Child#child{pid = Pid})
     end || Reply <- Replies],
    ok.
终止\u简单\u子项(子项、动力学、SupName)->
Pid=dict:fold(乐趣(Pid,参数,Pid)->
erlang:监视器(进程、Pid),
取消链接(Pid),
退出(Pid,子项退出原因(子项)),
[Pid | Pid]
完[]号,动力学),
TimeoutMsg={timeout,make_ref()},
TRef=超时\u启动(子项,TimeoutMsg),
{回复,Timedout}=
列表:foldl(
乐趣(_Pid,{回复,Timedout})->
{回复,Timedout1}=
请注意这里
TimeoutMsg->
剩余=PID--[P | |{P,}
{child_res(child,Reason,Timedout),Timedout};
{'EXIT',Pid,Reason}->
接收{'DOWN',MRef,进程,Pid,}->
{{error,Reason},Timedout}
结束
完,,
{[{Pid,Reply}| reples],Timedout1}
结束,{[],false},Pids),
超时\u停止(子级、TRef、TimeoutMsg、Timedout),
ReportError=关机错误报告器(SupName),
[案件答复]
{u Pid,ok}->ok;
{Pid,{error,R}->ReportError(R,Child{Pid=Pid})

结束| |回复是的,您可以有许多
receive
表达式。当对其中一个表达式求值时,它将从消息队列/邮箱中取出第一个匹配的消息(取您选择的名称),并将其余的消息留给下一个
receive
。使用
Pid!message
语法发送消息(唯一方法),是完全异步的,只需将消息添加到接收进程消息队列的末尾。
receive
是接收消息的唯一方法,即将消息从消息队列中取出。您永远无法将它们放回

Erlang中没有内置的同步消息传递,它是通过发送两条消息传递的:

  • “请求”进程向接收进程发送消息,然后进入
    receive
    等待回复

  • “接收”流程本身将在
    receive
    中获取消息,对其进行处理,将回复消息发送回“请求”流程,然后进入
    receive
    等待下一条消息

请记住,进程之间没有固有的联系,所有通信都是使用异步消息发送和
接收来完成的

所以在回答你的第二个问题时:你只能用
接收
表达式得到回复。这是唯一的方法

很抱歉有点迂腐,但Erlang既没有块也没有语句。它是一种函数式语言,只有始终返回值的表达式,即使返回值有时被忽略