Erlang - 产生进程和传递参数

Posted

技术标签:

【中文标题】Erlang - 产生进程和传递参数【英文标题】:Erlang - spawning processes and passing arguments 【发布时间】:2010-10-08 22:50:37 【问题描述】:

我一直遇到这个问题。我想生成进程并传递参数 不使用 MFA 形式(模块/函数/参数)给他们,所以 基本上不必导出我想要生成的函数 论据。我已经使用闭包解决了几次(有趣的) 并且让参数只是乐趣之外的绑定值(然后我在乐趣中引用),但它 限制我的代码结构...我只查看了文档和生成 有常规的 spawn/1 和 spawn/3 形式,没有别的......

我知道如果不使用 MFA 表单,在衍生进程中重新加载代码是不可能的,但衍生进程不是长期运行的,而且完成速度相对较快,所以这不是问题(我也想包含所有代码在一个模块级函数中,子作业被放置在该函数内的 funs 中)。

非常感谢 谢谢

【问题讨论】:

【参考方案1】:

实际上,Richard 为我指出了正确的方向,可以很好地避免这个问题(在回复我在 Erlang GoogleGroups 上发布的同一篇文章时): http://groups.google.com/group/erlang-programming/browse_thread/thread/1d77a697ec67935a

他的回答:

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

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

这对您的代码结构有何限制?

 /Richard 

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

【讨论】:

【参考方案2】:

简短的回答:你不能。 Spawn(以各种不同的形式)只需要一个 0-arity 函数。使用闭包并从生成函数中引入绑定变量是可行的方法,而不是使用诸如 ETS(即 Monster Overkill)之类的某种共享数据存储。

不过,我从未发现使用闭包会严重影响我的代码结构;你能举一个你遇到的问题的例子吗,也许有人可以帮你整理一下?

【讨论】:

spawn(Module, Function, Args) 怎么样? Args[term()] @agarrett:问题陈述“不使用 MFA 表格”。 抱歉,直到您刚才指出,我才意识到这意味着什么。谢谢:P【参考方案3】:

这是一个老问题,但我相信只要有一点创意就可以正确回答:

问题的目的是

调用函数

具有以下限制;

没有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 被调用以执行带有args 的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]).

【讨论】:

【参考方案4】:

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

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. 

【讨论】:

以上是关于Erlang - 产生进程和传递参数的主要内容,如果未能解决你的问题,请参考以下文章

(1) 如何向线程对应的函数传递参数?一个参数如何传递,多个参数如何传递? (2) 深入理解线程与进程的

C# 在 Linux 中使用进程。传递参数的问题

c#中关于启动进程时的参数传递问题

进程中参数的传递

C#进程间通信--API传递参数(SendMessage)

如何通过python子进程传递两个相同的参数?