Erlang World


top > concurrent programming > monitor

Monitor

モニター

モニターはリンクと違って、終了シグナルは双方に届けられるものではありません。 つまり終了シグナルが片側通行なのです。

モニターにおいては、

erlang:monitor(process,Pid)

を実行した側のみが終了プロセスを受け取ります。

システムプロセスと同様に、 モニター(関数を実行した側)は終了シグナルを受け取ってもメッセージとして処理されるだけです。

サンプルプログラムを通して確認してみます。

-module(mymonitor).
-export([start_monitor/0,  start_server/0]).

start_server() ->
    spawn(fun() -> server_loop() end).
    
server_loop() ->
    receive
        {add, X, Y} ->
            io:format("add: ~p~n",[X + Y]),
            server_loop()
    end.
    
start_monitor() ->
    spawn(fun() -> monitor_loop() end).
    
monitor_loop() ->
    receive
        {monitor,Pid} ->
            erlang:monitor(process, Pid),
            monitor_loop();
        
        {exit,Why} ->
            erlang:exit(Why);
        
        Other ->
            io:format("In moniter:~p~n",[Other]),
            monitor_loop()
    end.

前回までのプログラムと少し似ていますが、今回のプログラムは仲介サーバがありません。 代わりに、プロセスを監視するためのモニターサーバを利用しています。

モニターサーバには、モニターさせる、落とす、終了メッセージを受け取るという仕事があります。

それでは、実行してみましょう。

処理サーバを2つと、モニターサーバを作成します。
1> Pid = mymonitor:start_server().
<0.33.0>
2> Pid2 = mymonitor:start_server().
<0.35.0>
3> Monitor = mymonitor:start_monitor().
<0.37.0>

モニターに登録します
4> Monitor ! {monitor,Pid}.
{monitor,<0.33.0>}
5> Monitor ! {monitor,Pid2}.
{monitor,<0.35.0>}

処理サーバの一つをわざと落とす。
6> Pid ! {add,dog,cat}.
{add,dog,cat}

=ERROR REPORT==== 15-May-2008::23:53:04 ===
Error in process <0.33.0> with exit value: {badarith,[{mymonitor,server_loop,0}]}

In moniter:{'DOWN',#Ref<0.0.0.42>,process,<0.33.0>,
                   {badarith,[{mymonitor,server_loop,0}]}}

モニターは生きています。
7> is_process_alive(Monitor).
true

モニターを殺します。
8> Monitor ! {exit,killed}.
{exit,killed}

落としていない処理サーバは生きています。
9> is_process_alive(Pid2).
true

プロセスシステムで処理サーバとリンクしていたら、Pid2も死んでいました。 しかし、モニターはリンクとは違って終了シグナルは一方通行なのでPid2は生きています。

モニターの関数

関数(BIF erlang)役割
erlang:monitor(Type, Item)Typeは現在のところ、'process'のみ可能です。将来拡張される予定です。
ItemはプロセスIDです。Pidとして直接設定することも可能ですが、{RegName, Node} や RegName でも可能です。 RegNameは登録済みプロセスのアトムで、Nodeはノードです。 この関数の返り値はリファレンスです。

もしItemがダウンしたとき、この関数を実行したプロセスには'Down'メッセージが届きます。 書式は {'DOWN', MonitorRef, Type, Object, Info} です。 Object はPidで作成した場合はPid、 それ以外は {RegName,Node} となります。 Info はexitした理由です。 process_flag(trap_exit,true) が呼び出されていない状態で、Pidが死んでいれば例外を投げます。
erlang:demonitor(MonitorRef)モニターを解除します。
monitor_node(Node, Flag)ノードをモニターします。
Flagはboolean型でtrueならモニターをon、falseならモニターをoffします。

Yuichi ITO. All rights reserved.
mail to : ad
inserted by FC2 system