programming erlang ch9 - andstudy/forge GitHub Wiki
- ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ : link ์ฌ์ฉ, ๋ชจ๋ํฐ ์ฌ์ฉ
- link(P) : A <- > B, ์๋ก ์ฃฝ์ผ๋ฉด ์ฐ๊ฒฐ๋ ํ๋ก์ธ์ค์ ์ข ๋ฃ ์ ํธ๋ฅผ ๋ณด๋.
- ๋ณ๋ค๋ฅธ ์กฐ์น๋ฅผ ์ทจํ์ง ์์๋ค๋ฉด, ์ข ๋ฃ ์ ํธ๋ฅผ ๋ฐ์ผ๋ฉด ์์ ์ ํ๋ก์ธ์ค ์ญ์ ์ข ๋ฃ๋๋ค.
- ์์คํ ํ๋ก์ธ์ค : ์ข ๋ฃ ์ ํธ๋ฅผ ๋ฐ์ ๊ทธ ์ ํธ๋ฅผ ์ก์์ ์ฒ๋ฆฌํ ์ ์๋ ์ํ์ ํ๋ก์ธ์ค
์ด๋ค ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃํ ๊ฒฝ์ฐ์ ๋ญ๊ฐ ํ๋์ ์ทจํ๊ธฐ ์ํ ํธ๋ค๋ฌ ๋ง๋ค๊ธฐ ์์
<lib_misc.erl>
on_exit(Pid, Fun) ->
spawn(fun() ->
process_flag(trap_exit, true),
link(Pid),
receive
{'EXIT', Pid, Why} ->
Fun(Why)
end
end).
1> F = fun() ->
receive
X -> list_to_atom(X)
end
end.
2> Pid = spawn(F).
<0.61.0>
3> lib_misc:on_exit(Pid,
fun(Why) ->
io:format(" ~p died with:~p~n", [Pid, Why])
end).
<0.63.0>
4> Pid ! hello.
hello
<0.61.0> died with:{badarg, [{erlang,list_to_atom,[hello])])
- ์ผ๋ญ ์์คํ ์ ๋ง์ ์์ ๋ณ๋ ฌ ํ๋ก์ธ์ค๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฏ๋ก ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ค๋ฅ๋ ๋ค๋ฃฐ ์ ์์ด์ผ ํ๋ค.
- ๋ ์ค๋ฅ๋ฅผ ๋ค๋ฃจ๋ ํ๋ก์ธ์ค๊ฐ ๋ค๋ฅธ ๋จธ์ ์ผ ์๋ ์๋ค.
- ์ฐ๊ฒฐ(link)
- ๋ ํ๋ก์ธ์ค ๊ฐ์ ์ค๋ฅ์ ํ์ฐ ๊ฒฝ๋ก๋ฅผ ์ ์ํ๋ค.
- ํ ํ๋ก์ธ์ค๊ฐ ์ฃฝ์ผ๋ฉด ์ฐ๊ฒฐ๋ ๋๋จธ์ง ํ๋ก์ธ์ค์ ์ข ๋ฃ ์ ํธ๋ฅผ ๋ณด๋ธ๋ค.
- ์ฃผ์ด์ง ํ๋ก์ธ์ค์ ์ฐ๊ฒฐ๋์ด ์๋ ์ผ๋ จ์ ํ๋ก์ธ์ค๋ฅผ ๊ทธ ํ๋ก์ธ์ค์ ์ฐ๊ฒฐ ์งํฉ(link set)์ด๋ผ ๋ถ๋ฆ.
- ์ข
๋ฃ ์ ํธ(exit signal)
- ํ๋ก์ธ์ค๊ฐ ์ฃฝ์ ๋ ํด๋น ํ๋ก์ธ์ค๊ฐ ์์ฑํ๋ ์ด๋ค ๊ฒ.
- ์ ์ฃฝ์๋์ง ์ฌ์ ๋ฅผ exit(Reason) ์ผ๋ก ๋ช ์์ ์ผ๋ก ์ค์ ํ๊ฑฐ๋, ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฌต์ ์ผ๋ก ์ค์ ๋จ.
- exit ํจ์๋ก fake ์ข ๋ฃ ์ ํธ๋ฅผ ๋ณด๋ผ ์๋ ์์.
- ์์คํ
ํ๋ก์ธ์ค
- ์ข ๋ฃ ์ ํธ๋ฅผ ๋ฐ์ ๊ทธ ์ ํธ๋ฅผ ์ก์์ ์ฒ๋ฆฌํ ์ ์๋ ์ํ์ ํ๋ก์ธ์ค๊ฐ ์์คํ ํ๋ก์ธ์ค์ด๋ค.
- process_flag(trap_exit, true) ๋ฅผ ํธ์ถํ์ฌ ์ผ๋ฐ ํ๋ก์ธ์ค๋ฅผ ์์คํ ํ๋ก์ธ์ค๋ก ์ ํ์ํจ๋ค.
- exit(Pid, kill) - ์ฌ๊ธฐ๊พผ(rogue) ํ๋ก์ธ์ค๋ฅผ ์ฃฝ์ผ ๋ ์ฌ์ฉ
process_flag์ trap_exit ํ๋๊ทธ ์ค๋ช
| trap_exit | ์ข ๋ฃ ์ ํธ | ํ๋ |
|---|---|---|
| true | kill | ์ฃฝ๋๋ค. ์ข ๋ฃ ์ ํธ killed๋ฅผ ์ฐ๊ฒฐ ์งํฉ์ ๋ธ๋ก๋์บ์คํ |
| true | X | ๋ฉ์ผ ๋ฐ์ค์ {'EXIT', Pid, X}๋ฅผ ์ถ๊ฐํ๋ค. |
| false | normal | ๊ณ์ํ๋ค: ์๋ฌด ๊ฒ๋ ํ์ง ์๊ณ ์ ํธ๊ฐ ์ฌ๋ผ์ง๋ค. |
| false | kill | ์ฃฝ๋๋ค: ์ข ๋ฃ ์ ํธ killed๋ฅผ ์ฐ๊ฒฐ ์งํฉ์ผ๋ก ๋ธ๋ก๋์บ์คํ |
| false | X | ์ฃฝ๋๋ค: ์ข ๋ฃ ์ ํธ X๋ฅผ ์ฐ๊ฒฐ ์งํฉ์ผ๋ก ๋ธ๋ก๋์บ์คํ |
Pid = spawn(fun() -> ... end)
Pid = spawn_link(fun() -> ... end)
...
process_flag(trap_exit, true).
Pid = spawn_link(fun() -> ... end),
...
loop(...).
loop(State) ->
receive
{'EXIT', SomePid, Reason} ->
%% ์ค๋ฅ๋ก ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค
loop(State1);
...
end
์ฑ ์ฐธ๊ณ (180p ~ 185)
- @spec spawn_link(Fun) -> Pid
- atomicํ๊ฒ spawn๊ณผ link๋ฅผ ๋์์ ์ํํ๋ค.
- @spec process_flag(trap_exit, true)
- ํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์์คํ ํ๋ก์ธ์ค๋ก ๋ง๋ ๋ค.
- @spec link(Pid) -> true
- ํ๋ก์ธ์ค Pid๋ก ์ฐ๊ฒฐ์ด ์์ ๊ฒฝ์ฐ ์ฐ๊ฒฐ์ ์์ฑํ๋ค.
- @spec unlink(Pid) -> true
- ํ์ฌ ํ๋ก์ธ์ค์ ํ๋ก์ธ์ค Pid๊ฐ์ ๋ชจ๋ ์ฐ๊ฒฐ์ ์ ๊ฑฐํ๋ค.
- @spec exit(Why) -> none()
- ํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ Why๋ก ์ข ๋ฃ์ํจ๋ค.
- @spec exit(Pid, Why) -> true
- ์ข ๋ฃ ์ ํธ๋ฅผ ์ฌ์ Why์ ํจ๊ป ํ๋ก์ธ์ค Pid๋ก ๋ณด๋ธ๋ค.
- @spec erlang:monitor(process, Item) -> MonitorRef
- ๋ชจ๋ํฐ๋ฅผ ์ค์ ํ๋ค.
ํ๋ก์ธ์ค๊ฐ ๋น์ ์์ ์ธ ์ข ๋ฃ๋ฅผ ํ๋ฉด ๊ทธ๋ฃน์ ์๋ ๋ชจ๋ ํ๋ก์ธ์ค๊ฐ ์ฃฝ์.
์ฐ๊ฒฐ(link)์ ๋์นญ์ ์ด์ง๋ง, ๋ชจ๋ํฐ(monitor)๋ ๋น๋์นญ์ ์ธ ์ฐ๊ฒฐ์ด๋ค.
<lib_misc.erl>
keep_alive(Name, Fun) ->
register(Name, Pid = spawn(Fun)),
on_exit(Pid, fun(_Why) -> keep_alive(Name, Fun) end).