Understanding the return value of caviar

I'm starting with Erlang and can help a little to understand the different results when applying the PID returned from spawn/3 to the process_info/1 method.

Given this simple code in which the a/0 function is exported, which simply calls b/0 , which is waiting for a message:

 -module(tester). -export([a/0]). a() -> b(). b() -> receive {Pid, test} -> Pid ! alrighty_then end. 

... Please help me understand the reason for the different exit from the shell:


Example 1:

Here current_function of Pid displayed as tester:b/0 :

 Pid = spawn(tester, a, []). process_info( Pid ). > [{current_function,{tester,b,0}}, {initial_call,{tester,a,0}}, ... 

Example 2:

Here current_function of process_info/1 displayed as tester:a/0 :

 process_info( spawn(tester, a, []) ). > [{current_function,{tester,a,0}}, {initial_call,{tester,a,0}}, ... 

Example 3:

Here, current_function of process_info/1 displayed as tester:a/0 , but current_function of Pid is 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}}, ... 

I assume that when running spawn/3 , some asynchronous code happens in the background, but how does passing variables and passing arguments (especially in the last example) work, so that Pid gets one value and process_info/1 gets another?

Is there anything special about Erlang that binds variable assignments in such cases, but such a binding is not suggested for passing arguments?


EDIT:

If I use a function like this:

 TestFunc = fun( P ) -> P ! {self(), test}, flush() end. TestFunc( spawn(tester,a,[]) ). 

... the message is returned correctly from tester:b/0 :

 Shell got alrighty_then ok 

But if I use a function like this:

 TestFunc2 = fun( P ) -> process_info( P ) end. TestFunc2( spawn(tester,a,[]) ). 

... process_info/1 still shows tester:a/0 :

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

Not sure what to make of all this. Maybe I just need to accept it as above my pay level!

+4
source share
2 answers

If you look at the documents for spawn , it says that it returns the newly created Pid and puts the new process in the system scheduler queue. In other words, the process starts, but the caller continues to execute.

Erlang differs from some other languages ​​in that you do not need to explicitly enter controls, but you rely on a process scheduler to determine when to execute this process. In cases where you performed the Pid assignment, the scheduler had enough time to go to the child process, which subsequently made a b/0 call.

+8
source

It is really quite simple. The execution of the spawned process begins with a call (), which at some point soon calls b (), and then just sits there and waits until it receives a specific message. In the examples where you manage to immediately call process_info on the pid, you will catch it while the process is still executing the function (). In other cases, when there is some kind of delay, you will catch it after it has called b (). What about this confusing?

+6
source

All Articles