Я начинаю с Erlang и могу немного помочь понять разные результаты при применении PID, возвращаемого с spawn/3
, в метод process_info/1
.Понимание возвращаемого значения spawn
Учитывая этот простой код, в котором функция a/0
экспортируемый, которая просто вызывает b/0
, который ожидает сообщения:
-module(tester).
-export([a/0]).
a() ->
b().
b() ->
receive {Pid, test} ->
Pid ! alrighty_then
end.
... Пожалуйста, помогите мне понять причину различного выхода из оболочки:
Пример 1:
Здесь current_function
из Pid
показан как tester:b/0
:
Pid = spawn(tester, a, []).
process_info(Pid).
> [{current_function,{tester,b,0}},
{initial_call,{tester,a,0}},
...
Пример 2:
Здесь current_function
из process_info/1
показан как tester:a/0
:
process_info(spawn(tester, a, [])).
> [{current_function,{tester,a,0}},
{initial_call,{tester,a,0}},
...
Пример 3:
Здесь current_function
из process_info/1
показан как tester:a/0
, но current_function
из Pid
является 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, которое связывает присвоение переменной в таких случаях, но такая привязка не предлагается для передачи аргументов?
EDIT:
Если я использую такую функцию:
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', но получаю PID для' b/0'. Я имею в виду, что это было желаемое поведение, но я не мог понять его механику. Я думаю, Erlang просто знает, какой PID вернется в этом сценарии. – user113716
Pid не меняется - он «указывает» на процесс, который работает. По мере запуска он выполняет разные функции (в вашем случае A, затем B). 'current_function' показывает только, какую функцию выполняет этот процесс в тот момент, когда вы вызываете' process_info/1'. Если вам удастся взглянуть на него сразу, это будет в 'a/0', но если вы дадите ему достаточно долго, оно будет в' b/0'. –
Ах !!! Мое мышление было неправильным (очевидно). У меня было в голове, что когда вы создаете процесс (ссылаясь на функцию в 'spawn/3'), каждая функция, вызванная по пути, будет иметь свой собственный уникальный PID, связанный с ней. Но вместо этого процесс является более широким и может включать вызов многих функций, а PID - это просто ссылка на общий «процесс», который происходит. Если это звучит правильно (хотя и неуклюже поставлено), то я считаю, что понимаю. – user113716