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

andrew cooke andrew@REDACTED
Sun Apr 29 00:54:13 CEST 2007

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

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

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

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?


> 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