2011-06-20 101 views
4

我開始使用Erlang,並且在將spawn/3返回的PID應用於process_info/1方法時,可以使用一些幫助來理解不同的結果。瞭解spawn的返回值

鑑於這種簡單的代碼,其中a/0功能輸出,這只是調用b/0,它等待一個消息:

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

a() -> 
    b(). 
b() -> 
    receive {Pid, test} -> 
     Pid ! alrighty_then 
    end. 

...請幫助我理解從外殼輸出不同的原因:


實施例1:

這裏,的被示出爲tester:b/0

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

process_info(Pid). 

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

實施例2:

這裏,process_info/1current_function被示出爲tester:a/0

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

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

實施例3:

這裏,process_info/1current_function被示爲tester:a/0,但Pidcurrent_functiontester: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}}, 
... 

不知道做這一切的東西。也許我只需要接受它高於我的薪酬等級!

回答

8

如果您查看spawn的文檔,它會說它返回新創建的Pid並將新進程置於系統調度程序隊列中。換句話說,進程開始,但調用者繼續執行。

Erlang與其他一些語言的不同之處在於,您不必明確控制權限,而是依賴進程調度程序來確定何時執行哪個進程。如果您正在分配Pid,調度程序有足夠的時間切換到產生的進程,隨後調用b/0

+0

所以「系統調度程序」==「不會出汗細節」。我可以處理。我確實首先閱讀了文檔,這就是最初讓我開始思考這個問題的原因。我想知道爲什麼我產生'a/0',但是得到'b/0'的PID。我的意思是這當然是理想的行爲,但我無法理解它的機制。我猜Erlang只知道在這種情況下返回哪個PID。 – user113716

+6

Pid沒有改變 - 它「指向」正在運行的進程。運行時,它執行不同的功能(在你的情況A,然後B)。 'current_function'只顯示你在調用'process_info/1'的那一刻恰好執行哪個函數。如果你設法立即看它,它將會在'a/0'中,但是如果你給它足夠長的時間,它將會在'b/0'中。 –

+2

啊!我的想法是錯誤的(顯然)。在我的腦海中,當你產生一個進程時(通過引用'spawn/3'中的函數),沿途調用的每個函數都會擁有自己唯一的與之關聯的PID。但是,這個過程更爲廣泛,可能包含許多功能的調用,而PID僅僅是對正在發生的整個「過程」的參考。如果這聽起來正確(儘管笨拙),那麼我相信我是理解它。 – user113716

6

這真的很簡單。生成的進程的執行開始於對()的調用,在稍後的某個時刻調用b(),然後坐在那裏等待,直到它接收到特定的消息。在您設法立即調用pid上的process_info的示例中,您在進程仍在執行()時捕獲它。在其他情況下,當涉及一些延遲時,你在調用b()之後就會捕獲它。這是什麼讓人困惑?