在另一个节点出错后,Erlang 节点中的错误



我在同一台Windows机器上创建了2个Erlang节点,有两个cmd窗口:"unclient@MYPC"和"unserveur@MYPC",服务器代码非常简单:

-module(serveur).
-export([start/0,recever/0,inverse/1]). 
%%%%
start() -> 
process_flag(trap_exit,true), 
Pid=spawn_link(serveur,recever,[]), 
register(ownServer, Pid). 
%%%%
recever() -> 
receive 
{From, X} ->From ! {ownServer,1/X} 
end. 
%%%%
inverse(X) -> 
ownServer!{self(), X}, 
receive 
{'EXIT',_, _} ->start(), 
sorry;
{ownServer, Reply} ->Reply 
end. 

所以在服务器节点CMD我启动这个模块

c(serveur). 
serveur:start(). 

我测试了这个服务器:在我使用的服务器节点cmd上:

apply(serveur,inverse,[2]).

我收到了 0.5,我也尝试通过使用原子代替数字来导致错误:

apply(serveur,inverse,[a]).

shell显示错误并显示"抱歉",服务器通过自动重新启动孩子来正确返回其工作,因为这是一个系统进程,并且他会捕获孩子的退出。

现在在客户端节点,我使用 RPC 调用函数尝试连接,一切都很好,例如我尝试:

rpc:call('unserveur@MYPC' ,serveur,inverse,[2]).

在客户端节点cmd上,我收到:0.5

现在我使用原子将其发送到服务器以导致错误

rpc:call('unserveur@MYPC' ,serveur,inverse,[a]).

在客户端 cmd 节点: 我等待服务器的响应应该是"抱歉",但我没有收到任何东西,也没有更多的客户端提示:

unclient@MYPC 1>

我可以写,但 shell 不再执行我的指令,也没有任何提示。 在服务器节点: 我看到一个错误,然后服务器提示符正常返回

unserveur@MYPC 5>

我在服务器节点提示符下尝试了这个:

apply(serveur, inverse, [2]).

我遇到了一个错误,所以我通过在服务器节点 cmd 上调用 start(( 函数手动重新启动服务器,然后服务器恢复正常工作。 我在客户端调用之前和之后在服务器节点 cmd 上尝试了 self((,并且 pid 是相同的,这是逻辑,因为主服务器进程是一个系统进程,所以我的结果是他在收到 {'EXIT',...} 后没有执行代码。 为什么会这样?我无法理解这个错误,所以任何人都可以向我解释会发生什么?

发生这种情况是因为EXIT消息被发送到链接到服务器进程的任何进程,而服务器进程不一定与发送消息的进程相同。

当您在 shell 中运行它时,它可以工作,因为 shell 进程链接到服务器进程,并且 shell 进程也是调用inverse函数的进程。 但是,当您进行 RPC 调用时,将从不同的进程调用inverse函数。

尝试从客户端进行 RPC 调用,然后在服务器节点的 shell 中运行flush().,您应该会看到EXIT消息。

最新更新