spawn without linking?

Vance Shipley vances@REDACTED
Wed Apr 21 04:09:23 CEST 2004


On Tue, Apr 20, 2004 at 12:08:58PM -0700, Dustin Sallings wrote:
}  
}	I'm using erlang:monitor for an exercise, but I guess I'm not 
} 	entirely sure how to deal with abnormal exits that are propagated by links. 

If you link to another process you get a birectional link.
When one process exits it sends an {'EXIT', Reason} message
to the other.  Now these are normally trapped and result in
the process exiting.  If you are using spawn_link you are
saying that your process is a special process and can handle 
these messages, or that you want the calling process to die
when the spawned process does.

In the shell for instance you will see your shell process
goes away and is replaced by a new one:

1> self().
<0.24.0>
2> spawn_link(fun() -> receive after 1000 -> exit(timeout) end end).
<0.32.0>
** exited: timeout **
3> self().
<0.34.0>

To start turning our process into a special process we can ask
to trap exit signals:

4> process_flag(trap_exit, true).
false
5> spawn_link(fun() -> receive after 1000 -> exit(timeout) end end).
<0.37.0>
6> receive Exit -> Exit after 0 -> none end.
{'EXIT',<0.37.0>,timeout}
7> self().
<0.34.0>

Here's an example where we run SASL and use proc_lib:spawn_link/1:

3> application:start(sasl).
[... deleted more progress reports ...]
=PROGRESS REPORT==== 20-Apr-2004::21:50:48 ===
         application: sasl
          started_at: nonode@REDACTED

4> proc_lib:spawn_link(fun() -> receive after 1000 -> exit(timeout) end
end).
<0.55.0>
** exited: timeout **
5> 
=CRASH REPORT==== 20-Apr-2004::21:51:00 ===
  crasher:
    pid: <0.55.0>
    registered_name: []
    error_info: timeout
    initial_call: #Fun<erl_eval.20.54682479>
    ancestors: [<0.34.0>]
    messages: []
    links: [<0.34.0>]
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 233
    stack_size: 21
    reductions: 107
  neighbours:
    neighbour: [{pid,<0.34.0>},
                  {registered_name,[]},
                  {initial_call,{erlang,apply,2}},
                  {current_function,{shell,eval_loop,2}},
                  {ancestors,[]},
                  {messages,[]},
                  {links,[<0.23.0>,<0.55.0>]},
                  {dictionary,[]},
                  {trap_exit,false},
                  {status,waiting},
                  {heap_size,610},
                  {stack_size,4},
                  {reductions,1025}]


}  	I'd like the 'error' message to be handled properly by the echo 
}  process in a similar fashion to what monitor is doing, but it seems to 

You can do this:

mcpLoop(Procs) ->
    io:format("Looping with procs:  ~p\n", [Procs]),
    receive
        {sendto, N, Msg} ->
            lists:nth(N, Procs) ! Msg,
            mcpLoop(Procs);
+++     {'EXIT', Pid, _Reason} ->
+++         io:format("MCP got exit message for ~p\n", [Pid]),
+++         mcpLoop(mcpReplaceProcess(Pid, Procs));
        {'DOWN', _Ref, process, Pid, _Flag} ->
            io:format("MCP got down message for ~p\n", [Pid]),
            mcpLoop(mcpReplaceProcess(Pid, Procs));
        Msg ->
            io:format("MCP got ~p\n", [Msg]),
            mcpLoop(Procs)
    end.

mcpMonitor(N) ->
    Procs = listBuilder(fun () -> spawn_link(coursemp, echo, []) end, N, []),
    lists:foreach(fun (P) -> erlang:monitor(process, P) end, Procs),
+++ process_flag(trap_exit, true),
    mcpLoop(Procs).

Note that there is certainly redundancy with monitor.

}  	As of the 'error' message, the Mcp has died.  Does this mean the Mcp 
}  should *not* be linked to the processes it controls, or is there a 
}  different way to handle the errors?

The real solution is to use the design patterns in OTP.  You need a
top level supervisor which starts children and restarts them when
necessary.  The SASL application runs to handle error_reports, 
crash_reports and progress messages.  Your server processes are
instances of gen_server behaviours.  You start the application
using application:start/1.  Using this framework you will create
more resilient applications without having to think too hard about
it. 

	-Vance





More information about the erlang-questions mailing list