プロセスに名前を付ける/分散
Getting Started With Erlangの続き。3.3 Registered Process Namesと3.4 Distributed Programming。
プロセスに名前を付ける
「register(Atom,ProcessId).」でプロセス(ID)に名前を付けることができます。名前が付けられたプロセスには「<名前> ! <メッセージ>」のような感じでメッセージを送付できます。
昨日のサンプルを名前付きプロセスにしてみました。
-module(kitten). -export([start/1, run/1]). % 名前付きプロセス版ねこサーバー。 % メッセージに応じて一定のアクションを行う。 % プロセスには"kitten"の名前で登録される。 start(Name) -> PID = spawn( kitten, run, [Name] ), register(kitten, PID). % プロセスIDをkittenの名前で登録する。 run( Name ) -> receive run -> io:format( "~w : run!~n", [Name] ), run(Name); jump -> io:format( "~w : jump!~n", [Name] ), run(Name); stop -> io:format( "~w : stop~n", [Name] ), run(Name); sleep -> ok end.
起動して接続してみます。
3> kitten:start(mii). true 4> kitten ! run. mii : run! run 5> kitten ! stop. mii : stop stop 6> kitten ! jump. mii : jump! jump 7> kitten ! sleep. sleep
ふむ。
分散
分散も簡単にできるみたいです。例として同じPCの別のシェルで動作しているerlangプロセスにアクセスしてみます。手順は以下の通り
- サーバーとするシェルを起動。
- 起動時にオプションを指定して、分散ノードとして起動する。
- また、「magic cookie」をオプションで指定する。
- サーバーシェルでサーバーとするErlangプロセスを起動
- クライアントとするシェルを起動。
- こちらでも同様に、「分散ノード」、「magic cookie」のオプションを指定する。
- クライアントシェルからサーバーシェルのプロセスにメッセージを送付する。
magic cookieについて
不正アクセスを防ぐため、やりとりする2つのErlangシェルは「magic cookie」を共有している必要があります。「magic cookie」を簡単に設定する方法としては「シェル起動時に渡す」方法があり、今回はこれを使います。
1.サーバーとするシェルの起動
最初にサーバーとするシェルを、「分散ノード名(-sname)」と「magic cookie(-setcookie)」のオプション付きで起動します。
- 「分散ノード名(-sname)」は「<適当なシェル名>@ホスト名」の形式で指定します。
- ホスト名を省略した場合、自動で補完されます。
- 「-sname」ではなく「-name」を使うこともできます。ただし、ホスト名がFQDNになるので入力がちょっと面倒。
- 「magic cookie(-setcookie)」には適当な文字列を指定します。
>erl -sname server@localhost -setcookie test Eshell V5.5.4 (abort with ^G) (server@localhost)1>
2.サーバーとするErlangプロセスの起動
起動したサーバーシェルでサーバープロセスを起動します。上で作成したサンプルを使いました。
(server@localhost)1> c(kitten). {ok,kitten} (server@localhost)2> kitten:start(mii). true
3.クライアントとするシェルの起動。
続いて、クライアントとするシェルを起動します。こちらもサーバーシェルと同様に「分散ノード名(-sname)」と「magic cookie(-setcookie)」のオプション付きで起動します。
>erl -sname client@localhost -setcookie test Eshell V5.5.4 (abort with ^G) (client@localhost)1>
4.クライアントシェルからサーバーシェルのプロセスにメッセージを送付
クライアントからサーバーのシェルに接続し、メッセージを送付します。「!」のプロセスIDの部分を「{<プロセス名, <適当なシェル名>@ホスト名>}」のタプルにすることで別シェルのプロセスにメッセージを送信できます。
(client@localhost)1> {kitten, server@localhost} ! run. run
メッセージを送付するとサーバーのシェルに出力がありました。正しく送信できているようです!
(server@localhost)3> mii : run! (server@localhost)3>