【问题标题】:Can not spawn function on remote node with spawn(Node, Fun) in erlang无法在 erlang 中使用 spawn(Node, Fun) 在远程节点上生成函数
【发布时间】:2016-09-01 00:44:43
【问题描述】:

用分布式 erlang 进行实验,这就是我所拥有的:

 loop()->
    receive {From, ping} ->
            io:format("received ping from ~p~n", [From]),
            From ! pong,
            loop();
        {From, Fun} when is_function(Fun) ->
            io:format("executing function ~p received from ~p~n", [Fun, From]),
            From ! Fun(),
            loop()
    end.

    test_remote_node_can_execute_sent_clojure()->
        Pid = spawn(trecias, fun([])-> loop() end),
        Pid ! {self(), fun()-> erlang:nodes() end},
        receive Result -> 
            Result = [node()]
        after 300 ->
                  timeout
        end.

获取:Can not start erlang:apply,[#Fun<tests.1.123107452>,[]] on trecias

节点我在与节点“trecias”相同的机器上运行测试。两个节点都可以加载相同的代码。

任何想法有什么问题吗?

【问题讨论】:

    标签: erlang distributed


    【解决方案1】:

    spawn 调用中,您已将节点名称指定为trecias,但您需要指定完整的节点名称,包括主机名,例如trecias@localhost.

    此外,您传递给spawn/2 的函数必须接受零个参数,但上面代码中的函数接受一个参数(如果该参数不是空列表,则会崩溃)。改为fun() -> loop() end

    在远程节点上生成匿名函数时,您还需要确保在两个节点上都加载了相同版本的模块。否则你会得到一个badfun 错误。

    【讨论】:

    • 对,忘了@localhost 部分,谢谢。但是,spawn(Node, Fun) docs(erlang.org/doc/man/erlang.html#spawn-2) 说 Fun 必须接受空列表
    • 如果 Node 必须具有相同的可加载模块,那么 Spawn(Node, Fun) 的意义何在?为什么要制造您正在向远程节点发送 Fun 以在新进程中执行的错觉?那为什么不只 spawn(Node, M, F, A) 呢?
    • 文档讨论了将函数“应用”到空列表——这意味着使用空列表作为其参数列表,即将零参数传递给它。至于为什么必须在另一个节点上加载模块,使用 Erlang 分发时的常见情况是所有节点都有相同的代码,因此您通常只需发送对函数的引用。 spawn(Node, Fun)spawn(Node, M, F, A) 的区别在于前者可以访问生成它的函数中的变量。
    • @legoscia 这篇文章在link 继续。我发布了一个与您上次评论不一致的测试(在我看来)。我还做了一些测试,我调用了一个以前未加载的模块(即映射)(使用 m() shell 函数检查)并且它运行良好。所以我认为应该在文档中添加一些更准确的解释
    猜你喜欢
    • 1970-01-01
    • 2017-01-08
    • 2016-03-03
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    相关资源
    最近更新 更多