I have been trying to work with Programming Erlang , Version 2 ( Joe Armstrong's book). I am trying to solve the first problem in the Chap 13.
As a solution to the problem - I came up with this -
-module(errorhandle1).
-export([my_spawn/3,loop/1,test_func/0]).
my_spawn(Mod,Fun,Args) ->
%SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
%spawn(?MODULE , loop , [myspawn_helper(Mod,Fun,Args)]).
spawn(fun() -> loop(myspawn_helper(Mod,Fun,Args)) end).
myspawn_helper(Mod,Fun,Args) ->
statistics(wall_clock),
spawn_monitor(Mod,Fun,Args).
loop({SpPid,SpRef}) ->
io:format("Created Pid is : ~p~n",[SpPid]),
receive
{makeError,Msg} ->
SpPid ! Msg,
loop({SpPid,SpRef});
{'DOWN',SpRef, process,SpPid,Why} ->
{_, Time1} = statistics(wall_clock),
io:format("Down"),
io:format("Process spawn time = ~p microsecond ~n",[Time1])
end.
test_func() ->
receive
X ->
list_to_atom(X)
end.
The above code works and produces the desired output (first step is to solve the problem). Then I commented the line and came up with the following program , which is exactly same as the above one but , I use spawn/3 function instead of a spawn/1 and I dont seem to get the desired output.
-module(errorhandle1).
-export([my_spawn/3,loop/1,test_func/0]).
my_spawn(Mod,Fun,Args) ->
%SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
spawn(?MODULE , loop , [myspawn_helper(Mod,Fun,Args)]).
%spawn(fun() -> loop(myspawn_helper(Mod,Fun,Args)) end).
myspawn_helper(Mod,Fun,Args) ->
statistics(wall_clock),
spawn_monitor(Mod,Fun,Args).
loop({SpPid,SpRef}) ->
io:format("Created Pid is : ~p~n",[SpPid]),
receive
{makeError,Msg} ->
SpPid ! Msg,
loop({SpPid,SpRef});
{'DOWN',SpRef, process,SpPid,Why} ->
{_, Time1} = statistics(wall_clock),
io:format("Down"),
io:format("Process spawn time = ~p microsecond ~n",[Time1])
end.
test_func() ->
receive
X ->
list_to_atom(X)
end.
Steps to execute the above module: c(errorhandle1). Pid = errorhandle1:my_spawn(errorhandle1,test_func,[]). Pid ! {makeError,test}.
Can some please help me with my understanding of the usage of spawn/3 and spawn/1 ?
Thanks, Sathish.
spawn(fun() -> loop(myspawn_helper(Mod,Fun,Args)) end).
is not an equivalent of
spawn(?MODULE , loop , [myspawn_helper(Mod,Fun,Args)]).
in the second case [myspawn_helper(Mod,Fun,Args)]
is a parameter of function spawn/3
. The value of a parameter is evaluated before a function call. It means the call myspawn_helper(Mod,Fun,Args)
is made before the call to the spawn/3
outside of a new process in the original one. You can see it as this code
SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
spawn(?MODULE , loop , [SpawnedPidRef]).
the equivalent with spawn/1
would look like
SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
spawn(fun() -> loop(SpawnedPidRef) end).
Now you can see the difference. Only loop(SpawnedPidRef)
is actually done inside a new process. But in your first version you perform loop(myspawn_helper(Mod,Fun,Args))
in a new process. You can see it like
spawn(fun() ->
SpawnedPidRef = myspawn_helper(Mod,Fun,Args),
loop(SpawnedPidRef)
end).
which is very different code. (See the last two blocks. The last one is you first version and other one is your second version.)