この節では分散プログラミングに関連するBIFを扱います。 取り扱うモジュールは 「erlang」「net-kernel」「rpc」「global」です。
erlangモジュールは分散プログラミングでも役に立つ関数を持っています。
プロセスの生成
spawn(Node, Fun)
ノードNodeにfun Funを新しいプロセスとして開始する。
(luigi@ada)7> Fun = fun() ->
(luigi@ada)7> receive Y -> io:format("rec: ~p~n",[Y]) end
(luigi@ada)7> end.
#Fun<erl_eval.20.67289768>
(luigi@ada)8> Pid = spawn(mario@ada, Fun).
<5058.45.0>
(luigi@ada)9> Pid ! hello.
hello
rec: hello
spawn(Node, Module, Function, Args)
ノードNodeにモジュールModule、関数Function、
引数Argsのプロセスを新しく開始する。
(luigi@ada)3> Pid = spawn(mario@ada, node_test2, loop, []).
<5058.44.0>
リンク付きプロセス生成。単独のリンクとモニターは並列処理の場合と同じくPidを登録するだけです。
spawn_link(Node, Fun)
spawn_link(Node, Module, Function, Args)
ノードのモニター
monitor_node(Node, Flag)
ノードNodeを監視する。
Flagはtrueならばモニターを有効にし、falseなら無効にする。
モニターしているNodeが起動した場合に{nodeup, Node}
切断された場合に{nodedown, Node}というメッセージを返す。
ノードの状態を得る
node()
自分のノードの名前を得る。
(luigi@ada)10> node().
luigi@ada
nodes()
分散Erlangに参加しているノード名を返す。
(luigi@ada)11> nodes().
[mario@ada]
is_alive()
自ノードが分散Erlangに参加していればtrueを返す。
参加していなければfalseを返す。
(luigi@ada)12> is_alive().
true
node(Pid)
Pidを持つノードを返す。
誰も持っていなければ nonode@nohost を返す。
(luigi@ada)14> Pid = spawn(mario@ada, fun() -> receive Y -> Y end end).
<5058.46.0>
(luigi@ada)15> node(Pid).
mario@ada
このモジュールは指定されたノードの関数を利用する際に使います。 良く使う関数はあまり多くありません。
call(Node, Module, Function, Args) -> Res | {badrpc, Reason}
ノードNodeにあるモジュールModule、関数Fuction、引数Argsの関数を利用する。
問題が無い場合は実行結果を返し、問題がある場合は{badrpc, Reason}を返す。
cast(Node, Module, Function, Args) -> void()
call/4の返り値が無いタイプ。ノンブロッキング型である。
async_call(Node, Module, Function, Args) -> Key
ノンブロッキング型の呼び出し。返り値は Key である。
関数yield(Key)を使い結果を受け取る。
yield(Key) -> Res | {badrpc, Reason}
async_call/4を使って実行した関数の実行結果を受け取る。
async_call/4で指定された関数が終了していない場合は待たされる。
nb_yield(Key, Timeout) -> {value, Val} | timeout
Timeoutミリ秒待っても、async_call/4が実行した関数が終了しない場合は
timeoutを返す。終了している場合は{value, Val}を返す。
Valは実行結果である。
nb_yield(Key) -> {value, Val} | timeout
nb_yield(Key, 0)と同じ。
abcast(Nodes, Name, Msg) -> void()
リストNodesの全てのノードに対して、登録済みプロセスNameに向かってMsgを送信する。
abcast(Name, Msg) -> void()
abcast([node()|nodes()], Name, Msg)と同じである。
sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes}
リストNodesの全てのノードに対して、Nameが登録されているかを確認する。
登録されているノードはGoodNodesに、登録されていないノードはBadNodesに分けられる。
sbcast(Name, Msg) -> {GoodNodes, BadNodes}
sbcast([node()|nodes()], Name, Msg)と同じである。
ノード間で共有される登録済みプロセス
register_name(Name, Pid)
PidをNameとして登録する。登録したノード以外のノードにも知らせられる。
登録された後に参加したノードについても知らせられる。
unregister_name(Name) -> void()
登録済みプロセスの登録を解除する。
re_register_name(Name, Pid)
登録済みプロセスの名前を変更する。
whereis_name(Name) -> pid() | undefined
Nameが登録されているかを調べる。登録されていればPidを返し、
登録されていなければundefinedを返す。
send(Name, Msg) -> Pid
登録済みプロセスNameに対して、メッセージMsgを送信する。
ロック
set_lock(Id)
set_lock(Id, Nodes)
set_lock(Id, Nodes, Retries) -> boolean()
ロックをかけることにより排他制御を可能にする。Nodesが指定されていない場合は
全てのノードに適用される。Retriesはロックがかかっている場合に
何ミリ秒後にチェックするかということを記す。
del_lock(Id)
del_lock(Id, Nodes) -> void()
ロックを解除する。
分散Erlangへの参加
start([Name]) -> {ok, pid()} | {error, Reason}
start([Name, NameType]) -> {ok, pid()} | {error, Reason}
start([Name, NameType, Ticktime]) -> {ok, pid()} | {error, Reason}
分散Erlangに参加することが可能となる。
$ erl
Erlang (BEAM) emulator version 5.6.1 [source] [smp:2] [async-threads:0] [kernel-poll:false]
Eshell V5.6.1 (abort with ^G)
1> net_kernel:start([luigi,shortnames]).
{ok,<0.33.0>}
(luigi@ada)2>
接続管理
connect_node(Node)
Nodeと接続する。
erlang:disconnect_node(Node)の逆である。
allow(Nodes)
リストNodesにアクセスできるノードを制限する。
モニター
monitor_nodes(Flag) -> ok | Error
分散Erlangのグループに所属するノードの状態をモニターする。