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

636 views
537 views

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
636
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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

  1. 1. 株式会社エクストーン 下っ端 豊田陽一
  2. 2. !  プログラミングErlang ◦  Erlangの強力な並列性に触れてみよう "  モジュール "  関数定義 "  プロセス間のメッセージ送信 "  OTP
  3. 3. !  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 モジュール名の宣言 このモジュールで外部に公開する関数の宣言 関数定義
  4. 4. !  パターンマッチ ◦  引数のパターンに応じて呼び出すコード を変えることが出来る torpedo({_, submarine}) -> true; torpedo({_, 'heavy torpedo cruiser'}) -> true; torpedo({_, _}) -> false. 1> test1:torpedo({“Kitakami”, ‘heavy torpedo cruiser’). true 2> test1:torpedo({“Kongo”, battleship}). false
  5. 5. !  ガード ◦  パターンマッチより詳細な条件を記述 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
  6. 6. !  ガードと似ている 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’
  7. 7. !  spawn/1 ◦  関数を引数に取り、プロセスを作成 ◦  別のプロセスの実行結果は受け取れない 1> F = fun() -> 1 + 2 end. #Fun<erl_eval.20.80484245> 2> spawn(F). <0.35.0>
  8. 8. !  ! (Bang) ◦  Pidにメッセージを送信する 1> self() ! hello. hello 2> self() ! ‘hello world’. ‘hello world’ 3> flush(). Shell got hello Shell got 'hello world' ok
  9. 9. 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
  10. 10. !  プロセス間で作成される特定の関係 ◦  片方が死ぬともう片方も死ぬ 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>
  11. 11. !  プロセスの監視を行う ◦  プロセスが死んだらメッセージを受信 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).
  12. 12. !  実行してみる 1> spawn_monitor(fun test1:hoge/0). hoge {<0.44.0>,#Ref<0.0.0.111>} 2> test1:restarter(). hoge hoge hoge hoge
  13. 13. !  モニター開始/終了 ◦  erlang:monitor(process, Pid) -> Ref "  Pidのプロセスをモニター開始 ◦  erlang:demonitor(Ref) -> true "  モニター終了 !  監視している側にメッセージが届く ◦  { DOWN , Ref, process, Pid, Reason} "  DOWN :シンボル "  Ref:監視しているモニターオブジェクトの参 照 "  Pid:死んだプロセスのID "  Reason:プロセスが死んだ理由
  14. 14. !  プロセス通信の基本部分を見てみた ◦  次回はいよいよOTPに踏み込んで、実用 的なアプリケーションの話をします ◦  多分…

×