我开始使用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
的{{1}}显示为Pid
:
tester:b/0
示例2:
此处,Pid = spawn(tester, a, []).
process_info( Pid ).
> [{current_function,{tester,b,0}},
{initial_call,{tester,a,0}},
...
的{{1}}显示为current_function
:
process_info/1
示例3:
此处tester:a/0
的{{1}}显示为process_info( spawn(tester, a, []) ).
> [{current_function,{tester,a,0}},
{initial_call,{tester,a,0}},
...
,但current_function
的{{1}}为process_info/1
:
tester:a/0
我假设在调用current_function
时会在后台发生一些异步代码,但变量赋值和参数传递如何工作(特别是在最后一个示例中),Pid
得到一个值, tester:b/0
得到另一个?
在这种情况下,Erlang中是否存在绑定变量赋值的特殊内容,但是没有为参数传递提供这样的绑定?
修改
如果我使用这样的函数:
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
... TestFunc = fun( P ) -> P ! {self(), test}, flush() end.
TestFunc( spawn(tester,a,[]) ).
仍显示tester:b/0
:
Shell got alrighty_then
ok
不知道该怎么做。也许我只需要接受它高于我的工资等级!
答案 0 :(得分:9)
如果查看spawn的文档,它会返回新创建的Pid并将新进程放入系统调度程序队列。换句话说,进程启动但调用程序继续执行。
Erlang与其他语言的不同之处在于您不必显式地产生控制权,而是依靠进程调度程序来确定何时执行哪个进程。在您对Pid
进行分配的情况下,调度程序有足够的时间切换到生成的进程,随后调用b/0
。
答案 1 :(得分:6)
这真的很简单。生成进程的执行以对a()的调用开始,该调用稍后不久将调用b(),然后只是坐在那里等待直到它收到特定的消息。在您设法立即调用pid上的process_info的示例中,您在进程仍在执行a()时捕获它。在其他情况下,当涉及一些延迟时,在调用b()之后捕获它。这有什么令人困惑的呢?