为什么循环完成后我的进程不会死?

时间:2017-03-27 20:40:34

标签: erlang

这是我的代码:

-module(area_server0).
-export([loop/0]).
-include_lib("eunit/include/eunit.hrl").


loop() ->
    receive
        {circle, R} ->
            io:format("The area of a circle with radius ~w is: ~w~n",
                      [R, math:pi()*R*R]),
            loop();

        {rectangle, H, W} ->
            io:format("The are of a rectangle with sides ~w x ~w is: ~w~n",
                      [H, W, H*W]),
            loop();
        stop ->
            ok

    end.

在shell中:

~/erlang_programs$ erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V6.4  (abort with ^G)

1> Pid = spawn(area_server0, loop, []).
<0.34.0>

2> i().
...
...
kernel_safe_sup       gen_server:loop/6                        9              
<0.32.0>              erlang:apply/2                        2586    18929    0
                      c:pinfo/1                               50              
<0.34.0>              area_server0:loop/0                    233        9    0
                      area_server0:loop/0                      1              
Total                                                      44876   318773    0
                                                             220  

3> Pid ! stop.
stop

4> i().
...
...
kernel_safe_sup       gen_server:loop/6                        9              
<0.32.0>              erlang:apply/2                        2586    38126    0
                      c:pinfo/1                               50              
<0.34.0>              area_server0:loop/0                    233        9    1
                      area_server0:loop/0                      1              
Total                                                      42900   355567    1
                                                         220             

我预计不会看到过程&lt; 0.34.0&gt;在那里上市了。

现在,如果我改变我的代码以发送一个元组而不是一个原子的消息,那么进程就会死掉:

-module(area_server0).
-export([loop/0]).
-include_lib("eunit/include/eunit.hrl").


loop() ->
    receive
        {circle, R} ->
            io:format("The area of a circle with radius ~w is: ~w~n",
                      [R, math:pi()*R*R]),
            loop();

        {rectangle, H, W} ->
            io:format("The are of a rectangle with sides ~w x ~w is: ~w~n",
                      [H, W, H*W]),
            loop();
        {stop, _Pid} ->
            ok

    end.

在shell中:

~/erlang_programs$ erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V6.4  (abort with ^G)

1> c(area_server0).
{ok,area_server0}

2> Pid = spawn(area_server0, loop, []).
<0.43.0>

3> i().
...
...
kernel_safe_sup       gen_server:loop/6                        9              
<0.32.0>              erlang:apply/2                         987    19840    0
                      c:pinfo/1                               50              
<0.43.0>              area_server0:loop/0                    233        1    0
                      area_server0:loop/0                      1              
Total                                                      37492   862830    0
                                                             220  
ok

4> Pid ! {stop, self()}.
{stop,<0.32.0>}

5> i().
...
...
kernel_safe_sup       gen_server:loop/6                        9              
<0.32.0>              erlang:apply/2                        2586    39352    0
                      c:pinfo/1                               50              
Total                                                      38858   900091    0
                                                             219              
ok

显然,第一个例子是找不到原子stop的模式匹配。为什么不呢?

2 个答案:

答案 0 :(得分:2)

在你的第一个代码中,当你在shell中第二次调用i / 0时

进程循环/ 0邮箱不为空(num = 1)

表示您的停止消息与进程循环/ 0

不匹配

确保您的操作顺序正确无误:

  1. 编译

  2. 菌种

  3. I / 0

  4. 发送停止信息

  5. I / 0

答案 1 :(得分:0)

好的,看起来stop可能是erlang中的保留原子。如果我替换原子finishedxyz

,我的代码会按预期工作
loop() ->
    receive
        {circle, R} ->
            io:format("The area of a circle with radius ~w is: ~w~n",
                      [R, math:pi()*R*R]),
            loop();

        {rectangle, H, W} ->
            io:format("The are of a rectangle with sides ~w x ~w is: ~w~n",
                      [H, W, H*W]),
            loop();
        finished ->
            ok

    end.