programming erlang ch9 - andstudy/forge GitHub Wiki

9.1 ํ”„๋กœ์„ธ์Šค ์—ฐ๊ฒฐํ•˜๊ธฐ

  • ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ• : link ์‚ฌ์šฉ, ๋ชจ๋‹ˆํ„ฐ ์‚ฌ์šฉ
  • link(P) : A <- > B, ์„œ๋กœ ์ฃฝ์œผ๋ฉด ์—ฐ๊ฒฐ๋œ ํ”„๋กœ์„ธ์Šค์— ์ข…๋ฃŒ ์‹ ํ˜ธ๋ฅผ ๋ณด๋ƒ„.
  • ๋ณ„๋‹ค๋ฅธ ์กฐ์น˜๋ฅผ ์ทจํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์ข…๋ฃŒ ์‹ ํ˜ธ๋ฅผ ๋ฐ›์œผ๋ฉด ์ˆ˜์‹ ์ž ํ”„๋กœ์„ธ์Šค ์—ญ์‹œ ์ข…๋ฃŒ๋œ๋‹ค.
  • ์‹œ์Šคํ…œ ํ”„๋กœ์„ธ์Šค : ์ข…๋ฃŒ ์‹ ํ˜ธ๋ฅผ ๋ฐ›์•„ ๊ทธ ์‹ ํ˜ธ๋ฅผ ์žก์•„์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์˜ ํ”„๋กœ์„ธ์Šค

on_exit ํ•ธ๋“ค๋Ÿฌ ํ•˜๋‚˜

์–ด๋–ค ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒํ•  ๊ฒฝ์šฐ์— ๋ญ”๊ฐ€ ํ–‰๋™์„ ์ทจํ•˜๊ธฐ ์œ„ํ•œ ํ•ธ๋“ค๋Ÿฌ ๋งŒ๋“ค๊ธฐ ์˜ˆ์ œ

     <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])])

9.3 ์˜ค๋ฅ˜์˜ ์›๊ฒฉ ์ฒ˜๋ฆฌ

  • ์–ผ๋žญ ์‹œ์Šคํ…œ์€ ๋งŽ์€ ์ˆ˜์˜ ๋ณ‘๋ ฌ ํ”„๋กœ์„ธ์Šค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์˜ ์˜ค๋ฅ˜๋„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ๋˜ ์˜ค๋ฅ˜๋ฅผ ๋‹ค๋ฃจ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‹ค๋ฅธ ๋จธ์‹ ์ผ ์ˆ˜๋„ ์žˆ๋‹ค.

9.4 ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ์ƒ์„ธ

  • ์—ฐ๊ฒฐ(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๋ฅผ ์—ฐ๊ฒฐ ์ง‘ํ•ฉ์œผ๋กœ ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…

์ข…๋ฃŒ ์žก๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€์šฉ๋ฒ•

๊ด€์šฉ๋ฒ•1. ๋‚ด๊ฐ€ ์ƒ์„ฑํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉŽ๋”๋ผ๋„ ๋‚˜๋Š” ๋ชฐ๋ผ

    Pid = spawn(fun() -> ... end)

๊ด€์šฉ๋ฒ•2. ๋‚ด๊ฐ€ ์ƒ์„ฑํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ normal์ด ์•„๋‹ˆ๊ฒŒ ๋ฉŽ์œผ๋ฉด ๋‚˜๋„ ์ฃฝ์œผ๋ จ๋‹ค

    Pid = spawn_link(fun() -> ... end)

๊ด€์šฉ๋ฒ•3. ๋‚ด๊ฐ€ ์ƒ์„ฑํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉŽ์œผ๋ฉด ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค.

    ...
    process_flag(trap_exit, true).
    Pid = spawn_link(fun() -> ... end),
    ...
    loop(...).
    
    loop(State) ->
       receive
          {'EXIT', SomePid, Reason} ->
            %% ์˜ค๋ฅ˜๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•œ๋‹ค
            loop(State1);
          ...
       end

์ข…๋ฃŒ ์žก๊ธฐ ์žก๊ธฐ(๊ณ ๊ธ‰)

์ฑ…์ฐธ๊ณ  (180p ~ 185)

9.5 ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ

  • @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
    • ๋ชจ๋‹ˆํ„ฐ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

9.6 ์—ฐ๊ฒฐ๋œ ํ”„๋กœ์„ธ์Šค ์ง‘ํ•ฉ

ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋น„์ •์ƒ์ ์ธ ์ข…๋ฃŒ๋ฅผ ํ•˜๋ฉด ๊ทธ๋ฃน์— ์žˆ๋Š” ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฃฝ์Œ.

9.7 ๋ชจ๋‹ˆํ„ฐ

์—ฐ๊ฒฐ(link)์€ ๋Œ€์นญ์ ์ด์ง€๋งŒ, ๋ชจ๋‹ˆํ„ฐ(monitor)๋Š” ๋น„๋Œ€์นญ์ ์ธ ์—ฐ๊ฒฐ์ด๋‹ค.

9.8 ๊ณ„์† ์‚ด์•„ ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค

    <lib_misc.erl>
    keep_alive(Name, Fun) ->
       register(Name, Pid = spawn(Fun)),
       on_exit(Pid, fun(_Why) -> keep_alive(Name, Fun) end).
โš ๏ธ **GitHub.com Fallback** โš ๏ธ