0

对于有 Erlang 经验的人来说,这可能很容易,但我没有。我试图制作一个斐波那契进程树。然后它将接受一条消息,我可以在其中计算传递给它的那个节点下所有节点的总和。

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.

当我运行这个:

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

Erlang 控制台挂起。无法弄清楚为什么,但它与接收子句有关吗?

是的,这是作业,我的老师这周不在那里,这就是我在互联网上寻找替身的原因。

4

2 回答 2

1

是的,receive 子句阻塞了函数,因为它从不接收任何消息。但一般来说,这段代码并不是计算 fib 数的好方法。它可以通过一个简单的递归函数来完成,而不需要产生进程。

PS孩子1!sum + 1将失败,因为您尝试添加原子和整数

于 2012-11-19T22:08:28.513 回答
1

你需要有第一条消息。因为我也有任务,所以我可以提供一些提示:

  • 尝试将树的创建与总和计算分开。创建树,然后移动到您接收和发送消息的另一个函数。

  • 必须有人发送消息,您才能收到消息。

  • 您似乎对消息传递的方向感到困惑。您可能应该在树下发送一条消息(告诉您的孩子您正在计算节点),然后在树中向上发送一条消息(每个节点的结果)。这是一个算法的建议:

在每个节点中:

  1. 向两个孩子发送一条消息{get_sum, Id, Pid},其中 Id 是一些随机的唯一标识符,例如,来自now/0函数并且Pid来自self/0
  2. 在表格上恰好收到两个答案(每个孩子一个){sum, Id, Sum}Id与以前相同)。
  3. 两个总和相加,您为当前节点加 1。
  4. 将答案发送回树中的父级。

查看Erlang 调试器,它非常适合解决此类问题:

> c(modulename, [debug_info]).
> debugger:start().
(Module -> Interpret -> Pick the .erl file for the module you just compiled)
于 2012-11-19T22:43:50.080 回答