nilsi
nilsi

Reputation: 10761

Erlang console hangs with this codesnippet

This is probably easy for someone with experience in Erlang but I have none. Im trying to make a fibonacci tree of processes. It shall then accept a message where i can calculate the sum of all nodes under the one im passing it to.

create_fibtree(N) when N > 1 ->
Child1 = spawn(fun() -> create_fibtree(N-1) end),
Child2 = spawn(fun() -> create_fibtree(N-2) end),

receive 
    Sum ->
        Child1 ! sum + 1,
        Child2 ! sum + 1,
        io:format ("sum is ~p.~n", [Sum])
end;
create_fibtree(N) when N =< 1 ->
    ok.

When i run this:

c(fib_tree2).
{ok,fib_tree2}
2> fib_tree2:create_fibtree(10).

the Erlang console hangs. Cant figure out why but its something with the receive clause right?

And yes this is an homework, my teacher isn't there this week, that's why im looking for stand ins on the internet.

Upvotes: 0

Views: 284

Answers (2)

Emil Vikstr&#246;m
Emil Vikstr&#246;m

Reputation: 91983

You need to have a first message. Since I also have the assignment I can chip in with some hints:

  • Try to separate the tree creation from the sum calculation. Create the tree and then move over into another function where you receive and send messages.

  • Someone must send a message before you can receive it.

  • You seems to be confused about which direction the messages are passed. You should probably send one message down the tree (to tell your children that you are counting the nodes) and another upwards in the tree (the result from each node). Here is a suggestion for an algorithm:

In each node:

  1. Send a message {get_sum, Id, Pid} to both children, where Id is some random unique identifier, e.g., from the now/0 function and Pid is from self/0.
  2. Receive exactly two answers (one from each child) on the form {sum, Id, Sum} (where Id is the same as before).
  3. The two sums are added and you add 1 for the current node.
  4. Send the answer back up to the parent in the tree.

Check out the Erlang debugger which is great for troubleshooting this type of things:

> c(modulename, [debug_info]).
> debugger:start().
(Module -> Interpret -> Pick the .erl file for the module you just compiled)

Upvotes: 2

user1806568
user1806568

Reputation:

Right, the receive clause blocks the function as it never receives any messages. But this code in general is not a very good way to compute the fib numbers. It can be done with a simple recursive function without the need of spawning processes.

P.S. Child1 ! sum + 1, will fail, as you try to add atom and integer

Upvotes: 1

Related Questions