另一个节点出错后 erlang 节点中的错误
a bug in erlang node after an error at another node
我在同一台 Windows 机器上用两个 cmd windows:'unclient@MYPC' 和 'unserveur@MYPC' 创建了 2 个 erlang 节点,服务器代码非常简单:
-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 显示错误并显示 'sorry' 和服务器 returns 通过自动重新启动他的 child 来正常工作,因为它是一个系统进程并且他设下了 child 的出口。
现在在客户端节点,我使用 rpc 调用函数尝试连接,一切正常,例如我尝试:
rpc:call('unserveur@MYPC' ,serveur,inverse,[2]).
并且在客户端节点 cmd 我收到:0.5
现在我用atom发送到服务器导致错误
rpc:call('unserveur@MYPC' ,serveur,inverse,[a]).
在客户端 cmd 节点:
我等待服务器的响应应该是 'sorry' 但我没有收到任何东西,也没有更多的客户端提示:
unclient@MYPC 1>
我可以写但是shell不再执行我的指令并且没有任何提示。
在服务器节点:
我看到一个错误,然后服务器提示 returns 正常
unserveur@MYPC 5>
我在服务器节点提示符下试过这个:
apply(serveur, inverse, [2]).
我有一个错误,所以我通过在服务器节点 cmd 调用 start() 函数手动重启服务器,然后服务器 returns 正常工作。
我在客户端调用之前和之后在服务器节点 cmd 上尝试了 self() 并且 pid 是相同的,这是逻辑,因为主服务器进程是一个系统进程所以我的结果是他在接收后没有执行代码 {'EXIT',...}。
为什么会这样?我无法理解这个错误,所以任何人都可以向我解释发生了什么?
发生这种情况是因为 EXIT
消息被发送到链接到服务器进程的任何进程,该进程不一定是发送消息的同一个进程。
当您在 shell 中 运行 它时它起作用,因为 shell 进程链接到服务器进程,并且 shell 进程也是一个调用 inverse
函数。但是,当您进行 RPC 调用时,inverse
函数是从不同的进程调用的。
尝试从客户端进行 RPC 调用,然后在服务器节点的 shell 中 运行ning flush().
,您应该会看到 EXIT
消息.
我在同一台 Windows 机器上用两个 cmd windows:'unclient@MYPC' 和 'unserveur@MYPC' 创建了 2 个 erlang 节点,服务器代码非常简单:
-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 显示错误并显示 'sorry' 和服务器 returns 通过自动重新启动他的 child 来正常工作,因为它是一个系统进程并且他设下了 child 的出口。
现在在客户端节点,我使用 rpc 调用函数尝试连接,一切正常,例如我尝试:
rpc:call('unserveur@MYPC' ,serveur,inverse,[2]).
并且在客户端节点 cmd 我收到:0.5
现在我用atom发送到服务器导致错误
rpc:call('unserveur@MYPC' ,serveur,inverse,[a]).
在客户端 cmd 节点: 我等待服务器的响应应该是 'sorry' 但我没有收到任何东西,也没有更多的客户端提示:
unclient@MYPC 1>
我可以写但是shell不再执行我的指令并且没有任何提示。 在服务器节点: 我看到一个错误,然后服务器提示 returns 正常
unserveur@MYPC 5>
我在服务器节点提示符下试过这个:
apply(serveur, inverse, [2]).
我有一个错误,所以我通过在服务器节点 cmd 调用 start() 函数手动重启服务器,然后服务器 returns 正常工作。 我在客户端调用之前和之后在服务器节点 cmd 上尝试了 self() 并且 pid 是相同的,这是逻辑,因为主服务器进程是一个系统进程所以我的结果是他在接收后没有执行代码 {'EXIT',...}。 为什么会这样?我无法理解这个错误,所以任何人都可以向我解释发生了什么?
发生这种情况是因为 EXIT
消息被发送到链接到服务器进程的任何进程,该进程不一定是发送消息的同一个进程。
当您在 shell 中 运行 它时它起作用,因为 shell 进程链接到服务器进程,并且 shell 进程也是一个调用 inverse
函数。但是,当您进行 RPC 调用时,inverse
函数是从不同的进程调用的。
尝试从客户端进行 RPC 调用,然后在服务器节点的 shell 中 运行ning flush().
,您应该会看到 EXIT
消息.