[erlang-questions] Strange Socket Behaviour Was:Parents always take children with them?

andrew cooke <>
Sun Apr 29 00:54:13 CEST 2007


I was wrong about parent processes, but I now have no explanation for the
following.

-define(BASE_TCP, [list, inet, {packet, raw}, {active, false}]).

start() ->
    {ok, A} = inet:getaddr("10.2.0.1", inet),
    {ok, P} = gen_tcp:connect(A, 3128, ?BASE_TCP),
    spawn(fun() ->
                  io:format("blocking~n"),
                  X = gen_tcp:recv(P, 0),
                  io:format("~p~n", X),  %%% critical
                  io:format("done")
          end).

This blocks on recv (as expected).  But if the line marked "critical" is
omitted, then the call does not block ("done" is printed immediately).

As far as I can tell, Erlang has eager evaluation, and the above is a
simplified version of a similar problem in a more complex program where
the same problem occurs (recv fails to block) even though the result is
observed (the value {error, closed} was returned).  So I do not understand
the behaviour.

The "spawn" is necessary - without it, the recv blocks whether the
"critical" line is present or not.

The above was invoked with
  emake; erl -noshell +W i -run <module name>
in Erlang (BEAM) emulator version 5.5.4 [source] [64-bit]
[async-threads:0] [hipe]

Can someone explain this?  Is it a bug?

Thanks,
Andrew


> Do children processes die when the parent finishes (even normally)?
>
> If so, is there any way to stop this, or do I simply have to arrange that
> the last child is called directly rather than spawned (imagine a parent
> spawning a set of children and then exiting)?  Doing this (redirecting the
> parent thread "into" the final child) makes my code less symmetric than I
> would like :o)  I would prefer it if a parent could be made to wait for
> all children to terminate (if terminating normally).





More information about the erlang-questions mailing list