Erlang-生成进程和传递参数

Erlang-生成进程和传递参数,erlang,Erlang,我一直碰到这个。我希望生成进程并传递参数 在不使用MFA表单(模块/函数/参数)的情况下,将 基本上不需要导出我想要生成的函数 论据。我已经用闭包(fun's)解决了好几次这个问题 让参数仅仅是乐趣之外的绑定值(然后我在乐趣中引用),但是 限制我的代码结构。。。我只看了文档和生成 有常规的繁殖/1和繁殖/3形式,没有其他 我知道,如果不使用MFA表单,在派生进程中重新加载代码是不可能的,但是派生进程不是长时间运行的,并且完成得相对较快,因此这不是一个问题(我还希望在一个模块级函数中包含所有代码,

我一直碰到这个。我希望生成进程并传递参数 在不使用MFA表单(模块/函数/参数)的情况下,将 基本上不需要导出我想要生成的函数 论据。我已经用闭包(fun's)解决了好几次这个问题 让参数仅仅是乐趣之外的绑定值(然后我在乐趣中引用),但是 限制我的代码结构。。。我只看了文档和生成 有常规的繁殖/1和繁殖/3形式,没有其他

我知道,如果不使用MFA表单,在派生进程中重新加载代码是不可能的,但是派生进程不是长时间运行的,并且完成得相对较快,因此这不是一个问题(我还希望在一个模块级函数中包含所有代码,子作业放在该函数中的FUN中)

非常感谢
谢谢

简短的回答:你不能。Spawn(各种形式)只接受一个0-arity函数。使用闭包并从生成函数中引入绑定变量是一种方法,而不是使用诸如ETS之类的共享数据存储(这是一种怪兽式的滥杀)


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

事实上,Richard为我指出了正确的方向,很好地避免了这个问题(在回复我在Erlang GoogleGroups上发表的同一篇帖子时):

他的回答是: 通过“使用闭包”,我希望您的意思是:

Pid=spawn(fun()->any_函数(any、Number、Of、Arguments)end)

这将如何限制您的代码结构

 /Richard 


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

这是一个老生常谈的问题,但我相信可以用一点创造性来正确回答:

这个问题的目的是

  • 调用函数
有以下限制

  • M:F/A
    格式
  • 不导出调用的函数
这可以通过以下方式解决:

使用第一个限制,我们可以得到以下解决方案:

run()->
模块=模块,
函数=函数,
Args=[arg1,arg2,arg3],
erlang:spawn(模块、函数、参数)。
但是,在此解决方案中,需要导出函数

使用第二个限制(不导出调用的函数)和第1个限制,我们可以使用传统的erlang逻辑实现以下解决方案:

run()->
%%生成一个匿名乐趣并执行它
erlang:spawn(fun()->函数(arg1、arg2、arg3)结束)。
此解决方案在每次执行时都会生成匿名FUN,这可能是您的设计所要求的,也可能不是,因为垃圾收集器需要执行额外的工作(请注意,通常情况下,这是可以忽略的,并且问题可能只会在更大的系统中出现)

编写上述内容而不生成匿名FUN的另一种方法是生成一个
erlang:apply/2
,它可以使用给定参数执行函数

通过将函数Ref.传递给
erlang:apply/2
,我们可以引用本地函数并使用给定的参数调用它

以下内容实现了此解决方案:

run()->
%%本地(非导出)函数的函数引用
函数=有趣的函数/算术,
Args=[arg1,arg2,arg3],
erlang:spawn(erlang,apply,[Function,Args])。

编辑:可以在调用
erlang:apply/2
以使用args执行
fun()

%%https://github.com/erlang/otp/blob/71af97853c40d8ac5f499b5f2435082665520642/erts/preloaded/src/erlang.erl#L2888%% 生成并自动设置监视器。
-spec spawn_monitor(Fun)->{pid(),reference()}
Fun::function()。
当erlang:is_函数(F,0)->
erlang:spawn_opt(erlang,apply,[F,[]],[monitor]);
产卵监视器(F)->
erlang:error(badarg,[F])。

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

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. 


那么
spawn(模块、函数、参数)
Args
是一个
[term()]
@agarrett:Question声明“不使用MFA表单”。对不起,直到你刚才指出,我才意识到这意味着什么。谢谢:P