登録プロセス
登録プロセスとは、ある実行環境(ノード)内の任意の関数やプロセスから
一意に特定可能な名前を付けられたプロセスのことです。
関数内で別のプロセスで動作している関数のプロセス識別子を利用するには、
そのプロセス識別子を渡してあげる必要がありますが、
登録プロセスの場合には引数としてプロセス識別子を渡さなくても常に一意の
名前でそのプロセスにアクセスが可能となります。
プロセス識別子を使用した簡単なメッセージの送受信の例
10> Pid = spawn(fib, receiver, []).
<0.58.0>
11> Pid ! hello.
hello
12> Pid ! apple.
apple
17> fib:sender(orange, Pid).
orange
18>
%% 簡単なメッセージ受信関数
receiver() ->
receive
Msg -> Msg,
receiver()
end.
%% 送信用関数
sender(Msg, Pid) -> Pid ! Msg.
receiver()関数を登録プロセスとした場合には、その名前を使用して
登録プロセスを利用できます。
19> Pid = spawn(fib, receiver, []).
<0.79.0>
20> register(receiver_proc, Pid).
true
21> receiver_proc ! hello.
hello
22>
30> fib:sender(hello).
hello
%% 送信用関数(登録プロセス用)
sender(Msg) -> receiver_proc ! Msg.
フィボナッチ数を計算するサーバー
Erlangのメッセージを利用し、フィボナッチ数を計算するサーバーを作ります。
登録プロセスとすることで、名称を使用してサーバーにメッセージを送信することができます。
%% フィボナッチ計算サーバー
fibsvr() ->
receive
{0, Pid} when is_pid(Pid) ->
Pid ! 1,
fibsvr();
{1, Pid} when is_pid(Pid) ->
Pid ! 1,
fibsvr();
{X, Pid} when is_pid(Pid) ->
Pid ! fib(X - 1) + fib(X - 2),
fibsvr();
terminate -> terminate
end.
%% フィボナッチ計算クライアント
fibclt(X) ->
%% 登録プロセスを探す
IsALIVE = whereis(fibsvr),
if
%% 登録されていない時
IsALIVE == undefined ->
%% fibsvrを登録プロセスとして登録する
register(fibsvr, spawn(fib, fibsvr, []));
%% 登録されていればOK
true -> ok
end,
%% 登録プロセスにメッセージを送信する
fibsvr ! {X, self()},
%% メッセージを待つ
receive
R -> R
end.
1> fib:fibclt(30).
1346269
2> fib:fibclt(40).
165580141
まとめ
登録プロセスを使用してサーバー化したが、内部処理が並列化されていないので計算に時間がかかる
大きな数値の場合、応答性に問題が出てくる。
内部処理を並列処理にして応答性をあげるように改善が必要。