Upload
yoichi-toyota
View
407
Download
3
Embed Size (px)
Citation preview
株式会社エクストーン 下っ端 豊田陽一
! プログラミングErlang ◦ Erlangの強力な並列性に触れてみよう " モジュール " 関数定義 " プロセス間のメッセージ送信 " OTP
! 1つのファイルにまとめられた関数群
=== test1.erl === -module(test1) -export([add/2]) add(a, b) -> a + b. === test1.erl ===
1> c(test1) {ok,test1} 2> test1:add(1, 2). 3
モジュール名の宣言 このモジュールで外部に公開する関数の宣言
関数定義
! パターンマッチ ◦ 引数のパターンに応じて呼び出すコードを変えることが出来る
torpedo({_, submarine}) -> true; torpedo({_, 'heavy torpedo cruiser'}) -> true; torpedo({_, _}) -> false. 1> test1:torpedo({“Kitakami”, ‘heavy torpedo cruiser’). true 2> test1:torpedo({“Kongo”, battleship}). false
! ガード ◦ パターンマッチより詳細な条件を記述
torpedo_submarine(Level, Ko_Hyoteki) -> when Ko_Hyoteki =:= true ; Level >= 10 true; torpedo_submarine(_, _) -> false.
1> test1:torpedo_submarine(12, false). true 2> test1:torpedo_submarine(8, true). true 3> test1:torpedo_submarine(8, false). false
! ガードと似ている night_combat(MainWeapon, SubWeapon, Torpedo) -> if Torpedo >= 2 ; MainWeapon >= 3 ; MainWeapon =:= 2 andalso SubWeapon >= 1 ; MainWeapon >= 1 andalso MainWeapon =< 2 andalso Torpedo =:= 1 -> cutin; MainWeapon =:= 2 andalso SubWeapon =:= 0 andalso Torpedo =:= 0 ; MainWeapon =:= 1 andalso SubWeapon >= 1 andalso Torpedo =:= 0 ; MainWeapon =:= 0 andalso SubWeapon >= 2 andalso Torpedo =< 1 -> 'double strike'; true -> 'single strike' end.
1> test1:night_combat(1, 1, 1). cutin 2> test1:night_combat(1, 0, 0). ‘single strike’
! spawn/1 ◦ 関数を引数に取り、プロセスを作成 ◦ 別のプロセスの実行結果は受け取れない
1> F = fun() -> 1 + 2 end. #Fun<erl_eval.20.80484245> 2> spawn(F). <0.35.0>
! ! (Bang) ◦ Pidにメッセージを送信する
1> self() ! hello. hello 2> self() ! ‘hello world’. ‘hello world’ 3> flush(). Shell got hello Shell got 'hello world' ok
! receive ◦ メッセージを受信
1> Func = fun() -> receive {Pid, N} when N rem 2 =:= 0 -> Pid ! even; {Pid, _} -> Pid ! odd; end end. #Fun<erl_eval.20.80484245> 2> Rmt = spawn(Func). <0, 34, 0> 3> Rmt ! {self(), 4}. {self(), 4} 4> flush(). Shell got even ok
! プロセス間で作成される特定の関係 ◦ 片方が死ぬともう片方も死ぬ
1> self(). <0.41.0> 2> spawn_link( fun() -> timer:sleep(5000), exit(reason) end). <0.45.0> ** exception error: reason 3> self(). <0.51.0>
! プロセスの監視を行う ◦ プロセスが死んだらメッセージを受信
restarter() -> receive {'DOWN', Ref, process, Pid, Reason} -> spawn_monitor(fun test1:hoge/0), restarter() after 10000 -> ok end.
hoge() -> io:format("hoge~n", []), timer:sleep(5000).
! 実行してみる 1> spawn_monitor(fun test1:hoge/0). hoge {<0.44.0>,#Ref<0.0.0.111>} 2> test1:restarter(). hoge hoge hoge hoge
! モニター開始/終了 ◦ erlang:monitor(process, Pid) -> Ref " Pidのプロセスをモニター開始 ◦ erlang:demonitor(Ref) -> true " モニター終了
! 監視している側にメッセージが届く ◦ {‘DOWN’, Ref, process, Pid, Reason} " ‘DOWN’:シンボル " Ref:監視しているモニターオブジェクトの参照
" Pid:死んだプロセスのID " Reason:プロセスが死んだ理由
! プロセス通信の基本部分を見てみた ◦ 次回はいよいよOTPに踏み込んで、実用的なアプリケーションの話をします ◦ 多分…