Erlang - 产生进程和传递参数

时间:2009-02-20 21:41:34

标签: erlang

我一直在努力。我想生成进程并传递参数 他们没有使用MFA表格(模块/函数/参数),所以 基本上无需导出我想要生成的函数 参数。我使用闭包(乐趣)几次绕过这个 并且让参数只是在乐趣之外被绑定的值(然后我在乐趣中引用),但是它 限制我的代码结构......我只看了文档和产生 有常规的spawn / 1和spawn / 3形式,没有别的......

我理解,如果不使用MFA表单,生成的进程中的代码重新加载是不可能的,但是生成的进程不具有长期运行性并且相对快速地完成,因此这不是问题(我还想包含所有代码在一个模块级函数中,子作业被放置在该函数内部。)

非常感谢 谢谢

4 个答案:

答案 0 :(得分:12)

实际上,理查德指出我正确的方向,以避免这个问题(在我对Erlang GoogleGroups的同一篇文章的回复中): http://groups.google.com/group/erlang-programming/browse_thread/thread/1d77a697ec67935a

他的回答:

通过“使用闭包”,我希望你的意思是这样的:

Pid = spawn(fun() - > any_function(Any,Number,Of,Arguments)结束)

这会如何限制您的代码结构?

 /Richard 

感谢您及时评论我的问题。非常感谢

答案 1 :(得分:1)

简短的回答:你做不到。 Spawn(以其各种形式)仅采用0-arity函数。使用闭包并从产生函数引入绑定变量是可行的方法,而不是像ETS那样使用某种共享数据存储(Monster Overkill)。

我从未发现使用闭包来严重阻碍我的代码结构;你能举例说明你遇到的问题,或许有人可以为你整理一下吗?

答案 2 :(得分:1)

这是一个古老的问题,但我相信可以通过一点点创造力来正确回答:

问题的目标是

  • 调用功能

具有以下限制;

  • 没有M:F/A格式
  • 不导出调用的功能

这可以在下面解决;

使用第一个限制会导致我们找到以下解决方案:

run() ->
    Module = module,
    Function = function,
    Args = [arg1, arg2, arg3],
    erlang:spawn(Module, Function, Args).

但是,在此解决方案中,该功能需要导出。

与第二个限制一起使用第二个限制(不导出调用的函数)会导致我们使用常规的erlang逻辑得出以下解决方案:

run() ->
    %% Generate an anonymous fun and execute it
    erlang:spawn(fun() -> function(arg1, arg2, arg3) end).

由于垃圾收集器需要执行额外的工作,因此该解决方案会根据您的设计在每次执行时都可能会生成“匿名乐趣”(请注意,通常,这将是可忽略的,而问题只会是在较大的系统中可以看到)。

编写上面的而不产生的匿名乐趣的另一种方法是生成erlang:apply/2,它可以执行具有给定参数的功能。

通过传递功能参考。到erlang:apply/2,我们可以引用本地函数并使用给定的参数调用它。

以下实现了此解决方案:

run() ->
    %% Function Ref. to a local (non-exported) function
    Function = fun function/arity,
    Args = [arg1, arg2, arg3],
    erlang:spawn(erlang, apply, [Function, Args]).

编辑:可以在Erlang Src中找到这种类型的解决方案,据此,调用erlang:apply/2以执行带有实参的fun()

%% https://github.com/erlang/otp/blob/71af97853c40d8ac5f499b5f2435082665520642/erts/preloaded/src/erlang.erl#L2888%% Spawn and atomically set up a monitor.

-spec spawn_monitor(Fun) -> {pid(), reference()} when
      Fun :: function().
spawn_monitor(F) when erlang:is_function(F, 0) ->
    erlang:spawn_opt(erlang,apply,[F,[]],[monitor]);
spawn_monitor(F) ->
    erlang:error(badarg, [F]).

答案 3 :(得分:0)

首先,没有代码,我们不能为您提供很多帮助,因此,使用生成的过程来控制函数及其args的最佳方法是使用接收函数生成该过程,然后您将与您在发送和接收方法中的过程,请尝试:

Pid=spawn(Node, ModuleName, functionThatReceive, [])
%%or just spawn(ModuleName....) if the program is not %%distributed
Pid ! {self(), {M1, f1, A1}}, 
receive
{Pid, Reply} ->Reply
end, 

Pid ! {self(), {M2, f2, A2}}, 
receive
{Pid, Reply} ->Reply
end, 
....... 
functionThatReceive() ->
receive
{From, {M1, f1, A1}} ->From ! {self(), doSomething1} ;
{From, {M2, f2, A2}} ->From ! {self(), doSomething2} 
end. 

相关问题