14
株式会社エクストーン 下っ端 豊田陽一

Erlangのマルチプロセスを触ってみた

Embed Size (px)

Citation preview

Page 1: Erlangのマルチプロセスを触ってみた

株式会社エクストーン 下っ端 豊田陽一

Page 2: Erlangのマルチプロセスを触ってみた

! プログラミングErlang ◦ Erlangの強力な並列性に触れてみよう " モジュール " 関数定義 " プロセス間のメッセージ送信 "  OTP

Page 3: Erlangのマルチプロセスを触ってみた

! 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

モジュール名の宣言 このモジュールで外部に公開する関数の宣言

関数定義

Page 4: Erlangのマルチプロセスを触ってみた

! パターンマッチ ◦ 引数のパターンに応じて呼び出すコードを変えることが出来る

torpedo({_, submarine}) -> true; torpedo({_, 'heavy torpedo cruiser'}) -> true; torpedo({_, _}) -> false. 1> test1:torpedo({“Kitakami”, ‘heavy torpedo cruiser’). true 2> test1:torpedo({“Kongo”, battleship}). false

Page 5: Erlangのマルチプロセスを触ってみた

! ガード ◦ パターンマッチより詳細な条件を記述

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

Page 6: Erlangのマルチプロセスを触ってみた

! ガードと似ている 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’

Page 7: Erlangのマルチプロセスを触ってみた

! spawn/1 ◦ 関数を引数に取り、プロセスを作成 ◦ 別のプロセスの実行結果は受け取れない

1> F = fun() -> 1 + 2 end. #Fun<erl_eval.20.80484245> 2> spawn(F). <0.35.0>

Page 8: Erlangのマルチプロセスを触ってみた

!  ! (Bang) ◦ Pidにメッセージを送信する

1> self() ! hello. hello 2> self() ! ‘hello world’. ‘hello world’ 3> flush(). Shell got hello Shell got 'hello world' ok

Page 9: Erlangのマルチプロセスを触ってみた

!  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

Page 10: Erlangのマルチプロセスを触ってみた

! プロセス間で作成される特定の関係 ◦ 片方が死ぬともう片方も死ぬ

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>

Page 11: Erlangのマルチプロセスを触ってみた

! プロセスの監視を行う ◦ プロセスが死んだらメッセージを受信

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).

Page 12: Erlangのマルチプロセスを触ってみた

! 実行してみる 1> spawn_monitor(fun test1:hoge/0). hoge {<0.44.0>,#Ref<0.0.0.111>} 2> test1:restarter(). hoge hoge hoge hoge

Page 13: Erlangのマルチプロセスを触ってみた

! モニター開始/終了 ◦ erlang:monitor(process, Pid) -> Ref "  Pidのプロセスをモニター開始 ◦ erlang:demonitor(Ref) -> true " モニター終了

! 監視している側にメッセージが届く ◦  {‘DOWN’, Ref, process, Pid, Reason} "  ‘DOWN’:シンボル "  Ref:監視しているモニターオブジェクトの参照

"  Pid:死んだプロセスのID "  Reason:プロセスが死んだ理由

Page 14: Erlangのマルチプロセスを触ってみた

! プロセス通信の基本部分を見てみた ◦ 次回はいよいよOTPに踏み込んで、実用的なアプリケーションの話をします ◦ 多分…