我开始使用 Erlang,在应用从 spawn/3
返回的 PID 时,可以帮助理解不同的结果。到process_info/1
方法。
给定这个简单的代码,其中 a/0
函数被导出,它只是调用 b/0
,等待消息:
-module(tester).
-export([a/0]).
a() ->
b().
b() ->
receive {Pid, test} ->
Pid ! alrighty_then
end.
...请帮助我了解 shell 输出不同的原因:
示例 1:
在这里,
current_function
的 Pid
显示为 tester:b/0
:Pid = spawn(tester, a, []).
process_info( Pid ).
> [{current_function,{tester,b,0}},
{initial_call,{tester,a,0}},
...
示例 2:
在这里,
current_function
的 process_info/1
显示为 tester:a/0
:process_info( spawn(tester, a, []) ).
> [{current_function,{tester,a,0}},
{initial_call,{tester,a,0}},
...
示例 3:
在这里,
current_function
的 process_info/1
显示为 tester:a/0
,但 current_function
的 Pid
是 tester:b/0
:process_info( Pid = spawn(tester, a, []) ).
> [{current_function,{tester,a,0}},
{initial_call,{tester,a,0}},
...
process_info( Pid ).
> [{current_function,{tester,b,0}},
{initial_call,{tester,a,0}},
...
我假设在
spawn/3
时在后台发生了一些异步代码。被调用,但是变量赋值和参数传递是如何工作的(尤其是在最后一个例子中)这样 Pid
得到一个值,process_info/1
得到另一个?在这种情况下,Erlang 中是否有一些特殊的东西可以绑定(bind)变量赋值,但没有为参数传递提供这种绑定(bind)?
编辑:
如果我使用这样的函数:
TestFunc = fun( P ) -> P ! {self(), test}, flush() end.
TestFunc( spawn(tester,a,[]) ).
...消息从
tester:b/0
正确返回:Shell got alrighty_then
ok
但如果我使用这样的函数:
TestFunc2 = fun( P ) -> process_info( P ) end.
TestFunc2( spawn(tester,a,[]) ).
...
process_info/1
仍然显示 tester:a/0
:[{current_function,{tester,a,0}},
{initial_call,{tester,a,0}},
...
不知道该怎么做。也许我只需要接受它高于我的工资等级!
最佳答案
如果您查看 spawn 的文档它说它返回新创建的 Pid 并将新进程放入系统调度程序队列中。换句话说,进程开始了,但调用者继续执行。
Erlang 与其他一些语言的不同之处在于您不必显式地产生控制权,而是依靠进程调度程序来确定何时执行哪个进程。在您分配给 Pid
的情况下,调度程序有足够的时间切换到生成的进程,该进程随后调用了 b/0
.
关于erlang - 理解 spawn 的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6418106/