ksauzz weblog

technical note....

Erlの停止

erlangシェルを停止させるとき、q()だと停止に時間が掛かり、<Crt+G>, qだと即座に停止する。 この2つの違いを先日追いかけたので記録しておく。

q() の場合

まずはerlシェル上でq()を呼び出した場合の挙動。

1
2
3
Eshell V5.9.2  (abort with ^G)
1> q().
ok

マニュアルによるとこれはshell_default:q/0を呼び出している。

lib/stdlib/src/shell_default.erl
1
q()_____-> c:q().

最終的にinit:stop/0

stdlib/src/c.erl
1
2
q() ->
    init:stop().

init:stop/0はコードが負えなかったので、man initを読む。すると

All applications are taken down smoothly, all code is unloaded, and all ports are closed before the system terminates.

となっており、アプリケーションを正式な手順で停止させる雰囲気。

追記: たぶんerts/preloaded/src/init.erlから更に追える。

<Crl+G>, q の場合

次にCrl+G, qの場合。(JCLモードでq)

stdlib/src/c.erl
1
2
3
4
Eshell V5.9.2  (abort with ^G)
1>
User switch command
 --> q

User switch commandでgrepするとuser_drv.erlが使われている様子。

lib/kernel/src/user_drv.erl
1
2
3
4
5
6
7
8
switch_cmd({ok,[{atom,_,q}],_}, Iport, Oport, Gr) ->
    case erlang:system_info(break_ignored) of
    true ->_________________% noop
        io_request({put_chars,unicode,"Unknown command\n"}, Iport, Oport),
        switch_loop(Iport, Oport, Gr);
    false ->
        halt()
    end;

man erlangより

For integer Status the Erlang runtime system closes all ports and allows async threads to finish their operations before exiting.

まとめ

  • q() はapplicationの停止、コードのunloadをした上でruntimeを停止
  • <Crl+G>, qは単にruntimeを停止

諸々調べた後でマニュアルに停止方法が纏めてあることに気づいたが、 なぜかq()が紹介されていなかった。

4.4 How do I quit the Erlang shell?
To shut a system down cleanly, use init:stop().
Some quick ways are evaluating halt(). or Control+.
Control+C and Control+G give you access to menus.

そういえばerts/preloadedにはerlang, prim_inet, initモジュール等が入っているので追っかけてみると楽しいかもしれない。

Comments