关于supervisor 挂载woker和worker linke worker 的同样的结束等待


supervisor可以等待子worker结束后销毁自身,但是有的情况下我们并不是所有的进程都挂载在supervisor下面,而是link互相关联
 
1.这是都挂载在sup下面的情况

 
 
2.例如:这是link到worker的情况

现在我想让进程stop的时候,95不直接结束而是等待96结束后再结束那么应该怎么办呢
 
我们可以通过erlang:moniter/2来达到目的, 可以参考supervisor相关代码,
 
在95的terminate方法下面下如下代码,注意要合理设置after时间
 
 
terminate(Reason, State) ->
    ?Error(debug_logger, "e_test_server1 terminate start pid:~p", [self()]),
    io:format("~nserver1 i'm terminate:~p~n", [Reason]),
 
    Pid = State#state.linkpid,
    ?T("server1 terminate ~p",[Pid]),
    case monitor_child(Pid) of
        ok ->
            ?T("server1 terminate ok ~p",[Pid]),
            Pid ! {'EXIT', self(), shutdown},
            receive
                {'DOWN', _MRef, process, Pid, shutdown} ->
                    ?T("server1 terminate ok1 ~p",[Pid]),
                    ok;
                {'DOWN', _MRef, process, Pid, _OtherReason} ->
                    ?T("server1 terminate ok2 ~p",[Pid]),
                    %{error, OtherReason}
                    skip
            after 4000 ->
                    exit(Pid, kill),  %% Force termination.
                    receive
                        {'DOWN', _MRef, process, Pid, _OtherReason} ->
                            ?T("server1 terminate ok3 ~p",[Pid]),
                            %{error, OtherReason}
                            skip
                    end
            end;
        {error, _Reason} ->
            ?T("server1 terminate ok4 ~p",[Pid]),
            %{error, Reason}
            skip
    end,
 
    %timer:sleep(2000),
    ?Error(debug_logger, "e_test_server1 terminate end pid:~p", [self()]),
    io:format("~nserver1 ~s~n", ["end"]),
 
    ok.
 
code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
 
 
 
 
monitor_child(Pid) ->
 
    %% Do the monitor operation first so that if the child dies
    %% before the monitoring is done causing a 'DOWN'-message with
    %% reason noproc, we will get the real reason in the 'EXIT'-message
    %% unless a naughty child has already done unlink…
    erlang:monitor(process, Pid),
    unlink(Pid),
 
    receive
        %% If the child dies before the unlik we must empty
        %% the mail-box of the 'EXIT'-message and the 'DOWN'-message.
        {'EXIT', Pid, Reason} ->
            ?T("server1 monitor_child 1 ~p",[Pid]),
            receive
                {'DOWN', _, process, Pid, _} ->
                    ?T("server1 monitor_child 2 ~p",[Pid]),
                    {error, Reason}
            end
    after 0 ->
            %% If a naughty child did unlink and the child dies before
            %% monitor the result will be that shutdown/2 receives a
            %% 'DOWN'-message with reason noproc.
            %% If the child should die after the unlink there
            %% will be a 'DOWN'-message with a correct reason
            %% that will be handled in shutdown/2.
            ?T("server1 monitor_child 3 ~p",[Pid]),
            ok
    end.
 
 
 
 
 
 
 
 
 
注意:关于erlang:moniter/2
 

monitor(Type, Item) -> MonitorRef

Types:

Type = process
Item = pid() | {RegName, Node} | RegName
 RegName = atom()
 Node = node()
MonitorRef = reference()

The calling process starts monitoring Item which is an object of type Type.

Currently only processes can be monitored, i.e. the only allowed Type is process, but other types may be allowed in the future.

Item can be:

pid()

The pid of the process to monitor.

{RegName, Node}

A tuple consisting of a registered name of a process and a node name. The process residing on the node Node with the registered name RegName will be monitored.

RegName

The process locally registered as RegName will be monitored.

Note

When a process is monitored by registered name, the process that has the registered name at the time when monitor/2 is called will be monitored. The monitor will not be effected, if the registered name is unregistered.

A 'DOWN' message will be sent to the monitoring process if Item dies, if Item does not exist, or if the connection is lost to the node which Item resides on. A 'DOWN' message has the following pattern:

{'DOWN', MonitorRef, Type, Object, Info}

where MonitorRef and Type are the same as described above, and:

Object

A reference to the monitored object:

  • the pid of the monitored process, if Item was specified as a pid.
  • {RegName, Node}, if Item was specified as {RegName, Node}.
  • {RegName, Node}, if Item was specified as RegName. Node will in this case be the name of the local node (node()).
Info

Either the exit reason of the process, noproc (non-existing process), or noconnection (no connection to Node).

Note

If/when monitor/2 is extended (e.g. to handle other item types than process), other possible values for Object, and Info in the 'DOWN' message will be introduced.

The monitoring is turned off either when the 'DOWN' message is sent, or when demonitor/1 is called.

If an attempt is made to monitor a process on an older node (where remote process monitoring is not implemented or one where remote process monitoring by registered name is not implemented), the call fails with badarg.

Making several calls to monitor/2 for the same Item is not an error; it results in as many, completely independent, monitorings.

Note

The format of the 'DOWN' message changed in the 5.2 version of the emulator (OTP release R9B) for monitor by registered name. The Object element of the 'DOWN' message could in earlier versions sometimes be the pid of the monitored process and sometimes be the registered name. Now the Object element is always a tuple consisting of the registered name and the node name. Processes on new nodes (emulator version 5.2 or greater) will always get 'DOWN' messages on the new format even if they are monitoring processes on old nodes. Processes on old nodes will always get 'DOWN' messages on the old format.

posted on 2012-08-16 16:41  fangjie008  阅读(247)  评论(0编辑  收藏  举报

导航