Erlang: 簡単なサーバーとクライアントのメッセージプログラム
Erlangプログラミングではよく使う二つ以上の間でのメッセージ交換。
主に並行処理で必要不可欠の基礎ポイントをここで。
その簡単な例を作ってみた。
まずモジュールの名前をexample
-module(example).
関数を定義する。ここでは三つの関数を使うので三つとも定義する必要がある。関数名のあとの数字はパラメーターの数をあらわす。
-module(example). -export([main/0,server/0,client/2]).
ではまずMain関数から。新しいプロセスを作ることと、
-module(example). -export([main/0,server/0,client/2]). main() -> Server_function = spawn(fun server/0), %サーバーと言う関数をfunと名付け、Spawnを生成し、そのリターン値をServer_functionと名付ける spawn(example,client,[Server_function,1]), %Spawnでは上の書き方以外に、Spawn(モジュール名、関数名、 [その関数を呼ぶ際のパラメーター]) spawn(example,client,[Server_function,2]), spawn(example,client,[Server_function,3]), spawn(example,client,[Server_function,4]).
ここで重要ポイントがSpawn関数。以下がその使い方。
Pid = spawn(Fun)
Pid2 = spawn(mymodule, myfun, [Arg1, Arg2, ...])
Pid3 = spawn(OtherMachine, Fun)
Pid4 = spawn(OtherMachine, mymodule, myfun, [Arg1, Arg2, ...])
では次にServer関数を作る。これはサーバー上で何をするかを決める。
ここではシンプルに受け取った全てのメッセージをサーバーは表示させるだけにする。
-module(example). -export([main/0,server/0,client/2]). main() -> Server_function = spawn(fun server/0), %サーバーと言う関数をfunと名付け、Spawnを生成し、そのリターン値をServer_functionと名付ける spawn(example,client,[Server_function,1]), %Spawnでは上の書き方以外に、Spawn(モジュール名、関数名、 [その関数を呼ぶ際のパラメーター]) spawn(example,client,[Server_function,2]), spawn(example,client,[Server_function,3]), spawn(example,client,[Server_function,4]). server() -> receive({Pid,msg,N}) -> io:format("received from ~w ~b~n",[Pid,N]), server() end.
クライアントはどうやってサーバーにメッセージを送るか。
メッセージの送信の仕方は、
Pid ! Message
Spawnのリターン値であるプロセス識別子と!と送りたいメッセージを記す。
ではクライアント側の関数を作る。クライアントは何をするかと言うと、
Main関数で生成された四つのプロセスをサーバーに送り出すこと。
ただそれだけ。
-module(example). -export([main/0,server/0,client/2]). main() -> Server_function = spawn(fun server/0), %サーバーと言う関数をfunと名付け、Spawnを生成し、そのリターン値をServer_functionと名付ける spawn(example,client,[Server_function,1]), %Spawnでは上の書き方以外に、Spawn(モジュール名、関数名、 [その関数を呼ぶ際のパラメーター]) spawn(example,client,[Server_function,2]), spawn(example,client,[Server_function,3]), spawn(example,client,[Server_function,4]). server() -> receive({Pid,msg,N}) -> io:format("received from ~w ~b~n",[Pid,N]), server() end. dofor(I,F) -> if I > 0 -> F(), dofor(I-1,F); true -> done end. client(S,N) -> dofor(5, fun() ->% timer:sleep(100), S!{self(),msg,N}, done end).
上のdofor関数はただループするためだけのもの。一つ一つのプロセスをループし、サーバーに送る役割。
おしまい。