Почему оболочка 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}
Другие вопросы по тегам