了解spawn的返回值

use*_*716 4 erlang variable-assignment argument-passing spawn

我开始使用Erlang和可以使用一个小的帮助申请时的PID从返回理解的不同结果spawn/3process_info/1方法.

给定这个简单的代码,其中a/0导出函数,它只是调用b/0,等待消息:

-module(tester).
-export([a/0]).

a() ->
    b().
b() ->
    receive {Pid, test} ->
        Pid ! alrighty_then
    end.
Run Code Online (Sandbox Code Playgroud)

...请帮助我理解shell输出的不同原因:


例1:

在此,current_functionPid被示出为tester:b/0:

Pid = spawn(tester, a, []).

process_info( Pid ).

> [{current_function,{tester,b,0}},
    {initial_call,{tester,a,0}},
    ...
Run Code Online (Sandbox Code Playgroud)

例2:

在此,current_functionprocess_info/1被示出为tester:a/0:

process_info( spawn(tester, a, []) ).

> [{current_function,{tester,a,0}},
    {initial_call,{tester,a,0}},
    ...
Run Code Online (Sandbox Code Playgroud)

例3:

在此,current_functionprocess_info/1被示出为tester:a/0,但current_functionPidtester: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}},
    ...
Run Code Online (Sandbox Code Playgroud)

我假设spawn/3调用时会在后台发生一些异步代码,但是变量赋值和参数传递如何工作(特别是在最后一个例子中),这样Pid得到一个值,又process_info/1得到另一个?

在这种情况下,Erlang中是否存在绑定变量赋值的特殊内容,但是没有为参数传递提供这样的绑定?


编辑:

如果我使用这样的函数:

TestFunc = fun( P ) -> P ! {self(), test}, flush() end.

TestFunc( spawn(tester,a,[]) ).
Run Code Online (Sandbox Code Playgroud)

...从tester:b/0以下位置正确返回消息:

Shell got alrighty_then
ok
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用这样的函数:

TestFunc2 = fun( P ) -> process_info( P ) end.

TestFunc2( spawn(tester,a,[]) ).
Run Code Online (Sandbox Code Playgroud)

... process_info/1仍显示tester:a/0:

[{current_function,{tester,a,0}},
 {initial_call,{tester,a,0}},
 ...
Run Code Online (Sandbox Code Playgroud)

不知道该怎么做.也许我只需要接受它高于我的薪水等级!

Dav*_*don 9

如果你查看spawn的文档,它会返回新创建的Pid,并将新进程放在系统调度程序队列中.换句话说,进程启动但调用程序继续执行.

Erlang与其他语言的不同之处在于您不必显式地产生控制权,而是依靠进程调度程序来确定何时执行哪个进程.在您进行分配的情况下Pid,调度程序有足够的时间切换到生成的进程,随后进行调用b/0.

  • Pid没有改变 - 它"指向"正在运行的进程.在运行时,它会执行不同的功能(在您的情况下为A,然后是B).`current_function`只显示在调用`process_info/1`的那一刻,该进程恰好正在执行的函数.如果你设法立即查看它,它将在'a/0`中,但如果你给它足够长,它将在'b/0`中. (6认同)
  • 啊!!!我的想法是错误的(显然).当我产生一个进程(通过引用`spawn/3`中的函数)时,我已经知道了,沿途调用的每个函数都有自己唯一的PID关联它.但相反,该过程更广泛,并且可能包含许多函数的调用,而PID仅仅是对正在发生的整个"过程"的引用.如果这听起来是正确的(虽然笨拙地放),我相信我理解它. (2认同)
  • 是的,现在你已经拥有了!:) (2认同)

YOU*_*LID 6

这真的很简单.生成进程的执行以对a()的调用开始,该调用稍后不久将调用b(),然后只是坐在那里等待直到它收到特定的消息.在您设法立即调用pid上的process_info的示例中,您在进程仍在执行a()时捕获它.在其他情况下,当涉及一些延迟时,在调用b()之后捕获它.那令人困惑的是什么?