我開始使用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/1
current_function
被示出爲tester:a/0
:
process_info(spawn(tester, a, [])).
> [{current_function,{tester,a,0}},
{initial_call,{tester,a,0}},
...
實施例3:
這裏,process_info/1
current_function
被示爲tester:a/0
,但Pid
的current_function
是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在這種情況下綁定了變量賦值有什麼特殊之處,但是沒有提供這種綁定來傳遞參數嗎?
編輯:
如果我使用這樣的功能:
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}},
...
不知道做這一切的東西。也許我只需要接受它高於我的薪酬等級!
所以「系統調度程序」==「不會出汗細節」。我可以處理。我確實首先閱讀了文檔,這就是最初讓我開始思考這個問題的原因。我想知道爲什麼我產生'a/0',但是得到'b/0'的PID。我的意思是這當然是理想的行爲,但我無法理解它的機制。我猜Erlang只知道在這種情況下返回哪個PID。 – user113716
Pid沒有改變 - 它「指向」正在運行的進程。運行時,它執行不同的功能(在你的情況A,然後B)。 'current_function'只顯示你在調用'process_info/1'的那一刻恰好執行哪個函數。如果你設法立即看它,它將會在'a/0'中,但是如果你給它足夠長的時間,它將會在'b/0'中。 –
啊!我的想法是錯誤的(顯然)。在我的腦海中,當你產生一個進程時(通過引用'spawn/3'中的函數),沿途調用的每個函數都會擁有自己唯一的與之關聯的PID。但是,這個過程更爲廣泛,可能包含許多功能的調用,而PID僅僅是對正在發生的整個「過程」的參考。如果這聽起來正確(儘管笨拙),那麼我相信我是理解它。 – user113716