0

次のコードを検討してください。

-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().

上記のコードをシェルでテストすると、入力順序が異なる2つの異なる結果が得られますが、なぜですか?

最初の入力順序:

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

2番目の入力順序:

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)
4

1 に答える 1

1

この呼び出しadd_two:request(ddd)により、シェル プロセスが終了し、add_two がダウンしspawn_link()ます。これは、例外の前後でシェルの pid をチェックすることで確認できます。add_twoモジュールを含める必要さえありません。

12> self().
<0.61.0>
13> 2+2.
4
14> self().
<0.61.0>
15> 1/0.
** exception error: bad argument in an arithmetic expression
     in operator  '/'/2
        called as 1 / 0
16> self().
<0.69.0>
17> 

spawnの代わりに を呼び出すかspawn_link、生成されたプロセスで exit をトラップして処理することにより、この影響を回避できます。

于 2012-09-02T14:08:41.870 に答える