Почему оболочка erlang получает сообщение о выходе от порожденных процессов только один раз?
Вот код:
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [kernel-poll:false]
Eshell V9.1 (abort with ^G)
1> process_flag(trap_exit, true).
false
2> spawn_link(fun() -> exit(reason) end).
<0.63.0>
3> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.63.0>,reason}
4> spawn_link(fun() -> exit(reason) end).
<0.66.0>
5> receive X -> X after 0 -> 'end' end.
'end'
Почему оболочка erlang не получает сообщение о выходе от второго порожденного процесса?
1 ответ
Решение
После первого receive
преуспевает, X
привязывается к его возвращаемому значению, которое {'EXIT', <...>, reason}
, Поскольку вы используете одну и ту же переменную X
во-вторых receive
, receive
ждет сообщения, которое точно соответствует старому значению X
, который не будет соответствовать второму сообщению, потому что его PID отличается от первого.
Чтобы это исправить, вы можете использовать другое имя переменной:
1> process_flag(trap_exit, true).
false
2> spawn_link(fun() -> exit(reason) end).
<0.67.0>
3> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.67.0>,reason}
4> X.
{'EXIT',<0.67.0>,reason}
5> spawn_link(fun() -> exit(reason) end).
<0.71.0>
6> receive X2 -> X2 after 0 -> 'end' end.
{'EXIT',<0.71.0>,reason}
или вы можете "забыть" значение X
с помощью f/1
а затем использовать X
еще раз (это будет работать только в REPL):
7> spawn_link(fun() -> exit(reason) end).
<0.74.0>
8> f(X).
ok
9> receive X -> X after 0 -> 'end' end.
{'EXIT',<0.74.0>,reason}