erlang:监视器和'DOWN'消息

Che*_* Yu 5 erlang

仔细研究"gproc"项目的gproc_tests.erl文件时.我找到了以下代码."再见"消息在"erlang:monitor/2"之前发送,我认为有可能不会收到"DOWN"消息.这是对的吗?如果是这样,应该切换两条线,对吧?

t_simple_aggr_counter() ->
    ?assert(gproc:reg({c,l,c1}, 3) =:= true),
    ?assert(gproc:reg({a,l,c1}) =:= true),
    ?assert(gproc:get_value({a,l,c1}) =:= 3),
    P = self(),
    P1 = spawn_link(fun() ->
                gproc:reg({c,l,c1}, 5),
                P ! {self(), ok},
                receive
                {P, goodbye} -> ok
                end
            end),
    receive {P1, ok} -> ok end,
    ?assert(gproc:get_value({a,l,c1}) =:= 8),
    ?assert(gproc:update_counter({c,l,c1}, 4) =:= 7),
    ?assert(gproc:get_value({a,l,c1}) =:= 12),
    P1 ! {self(), goodbye},  %<<===========This line
    R = erlang:monitor(process, P1), %<<======This line
    receive {'DOWN', R, _, _, _} ->
        gproc:audit_process(P1)
    end,
    ?assert(gproc:get_value({a,l,c1}) =:= 7).
Run Code Online (Sandbox Code Playgroud)

小智 10

即使被监视的进程已经死亡,erlang:monitor/2调用仍然会向调用进程生成一个{'DOWN',...}消息.

例如:

1> F = fun() -> io:format("finished.~n") end.  
#Fun<erl_eval.20.111823515>
2> Pid = spawn(F).
finished.
<0.45.0>
3> erlang:monitor(process, Pid).    % process Pid has already exited.
#Ref<0.0.0.76>
4> flush().
Shell got {'DOWN',#Ref<0.0.0.76>,process,<0.45.0>,noproc}
ok
Run Code Online (Sandbox Code Playgroud)


Hyn*_*dil 5

根据文档erlang:monitor/2:如果Item死亡,如果Item不存在,或者如果连接丢失到Item所在的节点,则将'DOWN'消息发送到监视进程.