如何在Erlang中处理动态注册的进程和模式匹配?
当我向atom注册一个进程时,我可以通过atom而不是Pid交换地发送消息,这很方便。然而,模式匹配似乎将Pid和atom视为不同的实体,这是预期的,但并不方便。在我的示例中,如何在Erlang中处理动态注册的进程和模式匹配?,erlang,Erlang,当我向atom注册一个进程时,我可以通过atom而不是Pid交换地发送消息,这很方便。然而,模式匹配似乎将Pid和atom视为不同的实体,这是预期的,但并不方便。在我的示例中,{Pid,Response}模式不匹配,因为此范围中的Pid是一个原子,但作为响应发送的消息包含实际的Pid 有没有更好的方法来处理这个问题 该方案: -模块(ctemplate)。 -编译(全部导出)。 开始(安纳托姆,乐趣)-> Pid=繁殖(乐趣), 寄存器(AnAtom,Pid)。 rpc(Pid,请求)-> Pi
{Pid,Response}
模式不匹配,因为此范围中的Pid
是一个原子,但作为响应发送的消息包含实际的Pid
有没有更好的方法来处理这个问题
该方案:
-模块(ctemplate)。
-编译(全部导出)。
开始(安纳托姆,乐趣)->
Pid=繁殖(乐趣),
寄存器(AnAtom,Pid)。
rpc(Pid,请求)->
Pid!{self(),Request},
接收
{Pid,Response}->
反应;
任何->
io:format(“Finish(错误):~p~n”,[{Pid,Any}])
结束。
循环(X)->
接收
{发送方,任意}->
io:格式(“接收:~p~n”,[{发送方,任意}]),
发件人!{self(),“感谢联系我们”},
循环(X)
结束。
壳牌公司:
Eshell V5.10.2 (abort with ^G)
1> c(ctemplate).
{ok,ctemplate}
2> ctemplate:start(foo, fun() -> ctemplate:loop([]) end).
true
3> ctemplate:rpc(foo, ["bar"]).
Received: {<0.32.0>,["bar"]}
Finish (wrong):{foo,{<0.40.0>,"Thanks for contacting us"}}
ok
4> whereis(foo).
<0.40.0>
Eshell V5.10.2(使用^G中止)
1> c(ctemplate)。
{好的,ctemplate}
2> ctemplate:start(foo,fun()->ctemplate:loop([])end)。
真的
3> ctemplate:rpc(foo,[“bar”])。
收到:{,[“条”]}
完成(错误):{foo,{,“谢谢联系我们”}
好啊
4> (福)在哪里。
改用引用。您建议的示例实际上是REF更适合同步消息的原因之一。另一个原因是,有时您无法保证收到的消息是您实际期望的消息
因此,您的代码看起来像
rpc(PidOrName, Request) ->
Ref = make_ref(),
PidOrName ! {{self(), Ref}, Request},
receive
{{Pid, Ref}, Response} ->
Response;
Any ->
io:format("Finish (wrong):~p~n",[{PidOrName, Any}])
end.
loop(X) ->
receive
{{Pid, Ref}, Any} ->
io:format("Received: ~p~n",[{Sender, Any}]),
Sender ! {{self(), Ref}, "Thanks for contacting us"},
end,
loop(X).
关于您和我的代码的几点说明:
gen\u server
。gen\u server:call/2
和上面我的代码之间唯一的两个主要区别是超时(gen\u server
有超时),并且引用是通过监视远程进程创建的。这样,如果进程在抛出超时之前死亡,我们将立即收到一条消息。在许多情况下,它速度较慢,但有时证明它本身是有用的总的来说,尝试使用OTP并读取其代码。这很好,可以让您更好地了解Erlang应用程序应该如何工作。使用引用。您建议的示例实际上是REF更适合同步消息的原因之一。另一个原因是,有时您无法保证收到的消息是您实际期望的消息
rpc(Pid, Request) ->
Pid ! {self(), Request},
receive
{whereis(Pid), Response} ->
Response;
Any ->
io:format("Finish (wrong):~p~n",[{Pid, Any}])
end.
因此,您的代码看起来像
rpc(PidOrName, Request) ->
Ref = make_ref(),
PidOrName ! {{self(), Ref}, Request},
receive
{{Pid, Ref}, Response} ->
Response;
Any ->
io:format("Finish (wrong):~p~n",[{PidOrName, Any}])
end.
loop(X) ->
receive
{{Pid, Ref}, Any} ->
io:format("Received: ~p~n",[{Sender, Any}]),
Sender ! {{self(), Ref}, "Thanks for contacting us"},
end,
loop(X).
关于您和我的代码的几点说明:
gen\u server
。gen\u server:call/2
和上面我的代码之间唯一的两个主要区别是超时(gen\u server
有超时),并且引用是通过监视远程进程创建的。这样,如果进程在抛出超时之前死亡,我们将立即收到一条消息。在许多情况下,它速度较慢,但有时证明它本身是有用的总的来说,尝试使用OTP并读取其代码。这很好,可以让您更好地了解Erlang应用程序应该如何工作。使用引用。您建议的示例实际上是REF更适合同步消息的原因之一。另一个原因是,有时您无法保证收到的消息是您实际期望的消息
rpc(Pid, Request) ->
Pid ! {self(), Request},
receive
{whereis(Pid), Response} ->
Response;
Any ->
io:format("Finish (wrong):~p~n",[{Pid, Any}])
end.
因此,您的代码看起来像
rpc(PidOrName, Request) ->
Ref = make_ref(),
PidOrName ! {{self(), Ref}, Request},
receive
{{Pid, Ref}, Response} ->
Response;
Any ->
io:format("Finish (wrong):~p~n",[{PidOrName, Any}])
end.
loop(X) ->
receive
{{Pid, Ref}, Any} ->
io:format("Received: ~p~n",[{Sender, Any}]),
Sender ! {{self(), Ref}, "Thanks for contacting us"},
end,
loop(X).
关于您和我的代码的几点说明:
gen\u server
。gen\u server:call/2
和上面我的代码之间唯一的两个主要区别是超时(gen\u server
有超时),并且引用是通过监视远程进程创建的。这样,如果进程在抛出超时之前死亡,我们将立即收到一条消息。在许多情况下,它速度较慢,但有时证明它本身是有用的总的来说,尝试使用OTP并读取其代码。这很好,可以让您更好地了解Erlang应用程序应该如何工作。使用引用。您建议的示例实际上是REF更适合同步消息的原因之一。另一个原因是,有时您无法保证收到的消息是您实际期望的消息
rpc(Pid, Request) ->
Pid ! {self(), Request},
receive
{whereis(Pid), Response} ->
Response;
Any ->
io:format("Finish (wrong):~p~n",[{Pid, Any}])
end.
因此,您的代码看起来像
rpc(PidOrName, Request) ->
Ref = make_ref(),
PidOrName ! {{self(), Ref}, Request},
receive
{{Pid, Ref}, Response} ->
Response;
Any ->
io:format("Finish (wrong):~p~n",[{PidOrName, Any}])
end.
loop(X) ->
receive
{{Pid, Ref}, Any} ->
io:format("Received: ~p~n",[{Sender, Any}]),
Sender ! {{self(), Ref}, "Thanks for contacting us"},
end,
loop(X).
关于您和我的代码的几点说明:
gen\u server
。gen\u server:call/2
和上面我的代码之间唯一的两个主要区别是超时(gen\u server
有超时),并且引用是通过监视远程进程创建的。这样,如果进程在抛出超时之前死亡,我们将立即收到一条消息。在许多情况下,它速度较慢,但有时证明它本身是有用的