4

我开始使用 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.

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


示例 1:

在这里,current_functionofPid显示为tester:b/0

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

process_info( Pid ).

> [{current_function,{tester,b,0}},
    {initial_call,{tester,a,0}},
    ...

示例 2:

在这里,current_functionofprocess_info/1显示为tester:a/0

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

> [{current_function,{tester,a,0}},
    {initial_call,{tester,a,0}},
    ...

示例 3:

在这里,current_functionofprocess_info/1显示为tester:a/0,但current_functionofPidtester: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 中是否有一些特殊的东西可以绑定变量赋值,但没有为参数传递提供这种绑定?


编辑:

如果我使用这样的函数:

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}},
 ...

不知道该怎么做。也许我只需要接受它高于我的工资等级!

4

2 回答 2

9

如果您查看spawn的文档,它会说它返回新创建的 Pid 并将新进程放入系统调度程序队列中。换句话说,进程开始了,但调用者继续执行。

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

于 2011-06-20T23:00:03.647 回答
6

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

于 2011-06-20T22:42:14.967 回答