trap_exit cannot trap signal when exit/1 doesn't called explicitly

Joe Armstrong (TN/EAB) <>
Wed Aug 23 09:05:14 CEST 2006


Very good question! 
 
Why the program in the book works and why your program does not, depends
upon the behaviour
of the Erlang shell.
 
The Erlang shell used when the book was written and the Erlang shell in
the current Erlang distribution
work differently - this difference invalidates the example in the book.
 
When the book was written the Erlang shell evaluated each new command in
a fresh
process. Today the shell appears to evaluate all commands in a single
evaluator process 
and only restart the evaluator if it fails.
 
When you evaluate
 
              link_demo:demonstrate_normal() 
 
in the shell it merely creates a link to the demo process and do nothing
else
so there is no exit.
 
In the old Erlang shell (the one used when we wrote the book)
link_demo:demonstrate_normal()
was evaluated within a process (ie we spawn one process per shell
command) - this process
did two things, it first evaluated the link(whereis(demo)) command
linking itself to demo
then it died - that is where the exit comes from.
 
To emulate the old behaviour you can try this:
 
    > link_demo:start()
 
Then 
 
    > spawn(fun() -> link_demo:demonstrate_normal() end)
 
In this case you *will* get the behaviour you expect.
 
/Joe
 



________________________________

	From: 
[mailto:] On Behalf Of lang er
	Sent: den 22 augusti 2006 18:22
	To: 
	Subject: trap_exit cannot trap signal when exit/1 doesn't called
explicitly
	
	
	I run the example  link_demo(page 103) in Erlang book:
	
	
	-module(link_demo).
	
	%%
	%% Include files
	%%
	
	%%
	%% Exported Functions
	%%
	-export([start/0,demo/0,demonstrate_normal/0,
	                         demonstrate_exit/1,
demonstrate_error/0,demonstrate_message/1]). 
	
	%%
	%% API Functions
	%%
	
	start() ->
	    register(demo, spawn(link_demo, demo,  [])).
	
	demo() ->
	    process_flag(trap_exit, true),
	    demo1().
	
	demo1() ->
	    receive 
	        {'EXIT', From, normal} ->
	            io:format("Demo process received normal exit from
~w~n", [From]),
	            demo1();
	        {'EXIT', From, Reason} ->
	            io:format("Demo process received exit signal ~w from
~w~n", [Reason, From]), 
	            demo1();
	        finished_demo ->
	            io:format("Demo finished ~n", []);
	        Other ->
	            io:format("Demo process message ~w~n", [Other]),
	            demo1() 
	    end.
	
	
	%%
	%% Local Functions
	%%
	
	demonstrate_normal() ->
	    link(whereis(demo)).
	
	demonstrate_exit(What) ->
	    link(whereis(demo)),
	    exit(What).
	demonstrate_message(What) -> 
	    demo ! What.
	demonstrate_error()->
	    link(whereis(demo)),
	    1 = 2.
	
	-----------
	After start(), I call  demonstrate_normal(), demo process should
trap the exit(normal) signal, but it doesn't, 
	 and if  I call  demonstrate_exit(normal) , demo do trap the
exit(normal).
	
	The only difference between theses two situations is the exiting
process call exit/1 explicitly. 
	
	Must I call exit before existing ? 
	
	My environment: MacBook(Intel) 
	Erlang (BEAM) emulator version 5.5 [source] [async-threads:0]
	
	Eshell V5.5  (abort with ^G)
	1> 
	
	Thanks!
	Best Regards
	James
	

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20060823/ab0e6540/attachment.html>


More information about the erlang-questions mailing list