consider the code bleow:
-module(add_two).
-compile(export_all).
start()->
process_flag(trap_exit, true),
Pid = spawn_link(add_two, loop, []),
register(add_two, Pid),
ok.
request()->
add_two ! bad,
receive
{'EXIT', _Pid, Reason} -> io:format("self:~w~n", [{error, Reason}]);
{Result} -> io:format("result:~w~n", [Result])
after
1000->timeout
end.
loop()->
receive
bad -> exit(nogoodreason_bad);
{request, Pid, Msg} -> Pid ! {result, Msg + 2}
end,
loop().
when I test the code above in shell,I get two different results with different input order,but why?
first input order :
Eshell V5.9.1 (abort with ^G)
1> add_two:request(ddd).
** exception error: undefined function add_two:request/1
2> add_two:start().
ok
3> add_two:request().
self:{error,nogoodreason_bad}
ok
second input order:
Eshell V5.9.1 (abort with ^G)
1> add_two:start().
ok
2> add_two:request(ddd).
** exception error: undefined function add_two:request/1
3> add_two:request().
** exception error: bad argument
in function add_two:request/0 (add_two.erl, line 11)
The call
add_two:request(ddd)makes the shell process die, taking add_two down with it, due to thespawn_link()call. You can confirm this by checking the shell’s pid before and after an exception. It doesn’t even have to involve theadd_twomodule:You can avoid this effect either by calling
spawninstead ofspawn_link, or trapping and handling exits in the spawned process.