Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Elixir入門 第5回
「Visualixirで見るマルチプロセス」
2017/08/21 ver1.0作成
1
1. Elixirにおけるプロセス
2. プロセスの起動
3. メッセージ送受信
4. 双方向のメッセージ送受信
5. Visualixirでプロセスの可視化
6. プロセス発生を観測してみる
7. マルチコア/クラウド時代のプロセス指向
...
2
1.Elixirにおけるプロセス
3
1.Elixirにおけるプロセス
OS
Erlang VM
Process
Process
Process
spawn
spawn
send/receive
Erlang VM
Process
OS
Elixirにおける「プロセス」は、一般...
4
2.プロセスの起動
5
2.プロセスの起動
ElixirイメージをDockerで起動します
新たなElixirプロジェクトを作成します
プロジェクトをビルドします
lib/pass.exを、お好きなエディタで以下の通り、書き換えます
cd pass
# iex -...
6
2.プロセスの起動
ビルドし、通常の関数として実行すると、以下が表示されます
これが、spawnでプロセスを起動し、実行すると、以下のような、
関数の実行結果としての表示と、プロセスのIDが表示されます
iex> recompile()
i...
7
3.メッセージ送受信
8
3.メッセージ送受信:受信プロセスの起動
さきほどは、メッセージ表示するプロセスを起動しましたが、今度は、
メッセージを待ち受け、メッセージを受信したら表示するプロセスを
起動します
Erlang VM
confirm
#PID
<0. 1...
9
3.メッセージ送受信:受信プロセスの起動
さきほどは、メッセージ表示するプロセスを起動しましたが、今度は、
メッセージを待ち受け、メッセージを受信したら表示するプロセスを
起動します
受信プロセスを起動します
defmodule Pass ...
10
3.メッセージ送受信:メッセージ送信
受信プロセスのプロセスID宛に"hello"のメッセージを送信すると、
受け取ったメッセージを表示し、受信プロセスは終了します
受信プロセスは、一度受け取ると、プロセス終了するため、再送
しても受信し...
11
3.メッセージ送受信:受信(再帰)
繰り返し受信可能とするには、自身を再帰呼出します
これで再送しても、毎回メッセージを受信し、表示します
defmodule Pass do
…
def hear() do
receive do
{ tr...
12
3.メッセージ送受信:受信のパターンマッチング
受信プロセスは、第1引数として「true」のみ受け付けるパターン
マッチングになっています
true以外を送信すると、メッセージの受け取りがされません
iex> pid = spawn( P...
13
4.双方向のメッセージ送受信
14
4.双方向のメッセージ送受信
メッセージ受信後に、送信元へメッセージを返却する、双方向の
メッセージ送受信を行ってみます
Erlang VM
:hear_after
_say
#PID
<0.240.0>
iex
#PID
<0.209....
15
4.双方向のメッセージ送受信
メッセージ受信後に、送信元へメッセージを返却する、双方向の
メッセージ送受信を行ってみます
defmodule Pass do
…
def hear_after_say() do
receive do
{ s...
16
4.双方向のメッセージ送受信:受信後の返信確認
受信プロセスにメッセージを送り、受信したメッセージが表示され
るところまでは、これまでと同じですが、裏で返信をしています
自分宛に返ってきた返信を確認してみましょう
iex> recompi...
17
4.双方向のメッセージ送受信:返信確認②
receive~を手入力する代わりに、confirm()を使って、自分
宛に返ってきた返信を確認することもできます
なお、confirm()は、もし返信が無かった場合、ずっと待ち続け
てしまいます...
18
4.双方向のメッセージ送受信:返信タイムアウト
チェックから5秒間、返信無なら、タイムアウトさせます
これで返信が無くても、待ち続けないようになります
defmodule Pass do
…
def confirm() do
receiv...
19
5.Visualixirでプロセスの可視化
20
5. Visualixirでプロセスの可視化
Visualixirは、Elixirのプロセスを可視化するツールです
https://github.com/koudelka/visualixir
顕微鏡で見る微生物のような不思議なUIで可視...
21
githubからリポジトリをcloneして、ビルドした後、Visualixirを
動かすPhoenixを起動します
ブラウザで「http://localhost:4000/」を表示すると、
Visualixirが表示されます
5. Vis...
22
6.プロセス発生を観測してみる
23
6.プロセス発生を観測してみる
Passモジュールを繰り返しspawnするrepeat_spawn()にて、
Visualixirでプロセスが増殖していく様を観察してみます
別コンソールで、repeat_spawn()を以下のように起動し...
24
6.プロセス発生を観測してみる
より高速にプロセスを増殖させてみましょう
別コンソールで、repeat_spawn_nosleep()を起動すると、
アッと言う間にVisualixir上がプロセスで埋め尽くされるのですが、
その状態でも、...
25
7.マルチコア/クラウド時代のプロセス指向
26
7.マルチコア/クラウド時代のプロセス指向
今回は、Elixirのプロセスについてご説明しました
並行分散のベースとなる、プロセスの生成と通信による組み立て
が「そこまで難しく無いかも?」と思っていただけたら、この入門と
しては大成功です...
27
ご清聴ありがとうございます
Upcoming SlideShare
Loading in …5
×

Elixir入門「第5回:Visualixirで見るマルチプロセス」

534 views

Published on

Elixirの「プロセス生成」と「プロセス間通信」を説明した後、プロセス可視化ツール「Visualixir」にて、Elixirのプロセスが増殖する様を眺めてみます

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Elixir入門「第5回:Visualixirで見るマルチプロセス」

  1. 1. Elixir入門 第5回 「Visualixirで見るマルチプロセス」 2017/08/21 ver1.0作成
  2. 2. 1 1. Elixirにおけるプロセス 2. プロセスの起動 3. メッセージ送受信 4. 双方向のメッセージ送受信 5. Visualixirでプロセスの可視化 6. プロセス発生を観測してみる 7. マルチコア/クラウド時代のプロセス指向 目次
  3. 3. 2 1.Elixirにおけるプロセス
  4. 4. 3 1.Elixirにおけるプロセス OS Erlang VM Process Process Process spawn spawn send/receive Erlang VM Process OS Elixirにおける「プロセス」は、一般的なプロセスというイメージより は、スレッドに近いイメージです • ElixirにおけるプロセスはOSのプロセスでは無い • OSのプロセスとして起動する「Erlang VM」上で管理される 軽量プロセスを指す http://elixir-ja.sena-net.works/getting_started/11.html send/receive spawn
  5. 5. 4 2.プロセスの起動
  6. 6. 5 2.プロセスの起動 ElixirイメージをDockerで起動します 新たなElixirプロジェクトを作成します プロジェクトをビルドします lib/pass.exを、お好きなエディタで以下の通り、書き換えます cd pass # iex -S mix > docker run --rm -v /c/piacere/code:/code -i -t trenpixster/elixir /bin/bash # mix new pass defmodule Pass do def say( message "こんにちは。" ), do: IO.puts( message ) end
  7. 7. 6 2.プロセスの起動 ビルドし、通常の関数として実行すると、以下が表示されます これが、spawnでプロセスを起動し、実行すると、以下のような、 関数の実行結果としての表示と、プロセスのIDが表示されます iex> recompile() iex> Pass.say こんにちは。 :ok iex> spawn( Pass, :say, [] ) こんにちは。 #PID<0.1805.0> 第1引数:モジュール名 第2引数:関数名 ※「:」を付ける 第3引数:関数に渡す引数のリスト ※参照:第14章 P162
  8. 8. 7 3.メッセージ送受信
  9. 9. 8 3.メッセージ送受信:受信プロセスの起動 さきほどは、メッセージ表示するプロセスを起動しましたが、今度は、 メッセージを待ち受け、メッセージを受信したら表示するプロセスを 起動します Erlang VM confirm #PID <0. 1768.0> iex #PID <0.209.0>, spawn send(hello) hello recieve
  10. 10. 9 3.メッセージ送受信:受信プロセスの起動 さきほどは、メッセージ表示するプロセスを起動しましたが、今度は、 メッセージを待ち受け、メッセージを受信したら表示するプロセスを 起動します 受信プロセスを起動します defmodule Pass do … def confirm() do receive do { true, message } -> IO.puts( "受信メッセージ'#{message}'。" ) end IO.puts( "------ confirm() end ------" ) end … iex> recompile() iex> pid = spawn( Pass, :confirm, [] ) #PID<0.1768.0> ※参照:第14章 P163
  11. 11. 10 3.メッセージ送受信:メッセージ送信 受信プロセスのプロセスID宛に"hello"のメッセージを送信すると、 受け取ったメッセージを表示し、受信プロセスは終了します 受信プロセスは、一度受け取ると、プロセス終了するため、再送 しても受信しません iex> send( pid, { true, "hello" } ) 受信メッセージ'hello'。 {true, "hello"} ------ confirm() end ------ iex> send( pid, { true, "hello" } ) {true, "hello"} 「受信メッセージ'hello'。」が表示されない ※参照:第14章 P163~164
  12. 12. 11 3.メッセージ送受信:受信(再帰) 繰り返し受信可能とするには、自身を再帰呼出します これで再送しても、毎回メッセージを受信し、表示します defmodule Pass do … def hear() do receive do { true, message } -> IO.puts( "受信メッセージ'#{message}'。再度メッセージを受け取れます。" ) end hear() IO.puts( "------ hear() end ------" ) … # iex -S mix iex> pid = spawn( Pass, :hear, [] ) #PID<0.496.0> iex> send( pid, { true, "hello" } ) 受信メッセージ'hello'。再度メッセージを受け取れます。 {true, “hello"} iex> send( pid, { true, “world" } ) 受信メッセージ‘world'。再度メッセージを受け取れます。 {true, "world"} ※参照:第14章 P164、166
  13. 13. 12 3.メッセージ送受信:受信のパターンマッチング 受信プロセスは、第1引数として「true」のみ受け付けるパターン マッチングになっています true以外を送信すると、メッセージの受け取りがされません iex> pid = spawn( Pass, :hear, [] ) #PID<0.387.0> iex> send( pid, { "hoge", "hello" } ) {"hoge", "hello"} iex> send( pid, { :ok, "hello" } ) {:ok, "hello"} defmodule Pass do … def hear() do receive do { true, message } -> IO.puts( "受信メッセージ'#{message}'。" ) … 受け取ったメッセージが表示されない 受け取ったメッセージが表示されない
  14. 14. 13 4.双方向のメッセージ送受信
  15. 15. 14 4.双方向のメッセージ送受信 メッセージ受信後に、送信元へメッセージを返却する、双方向の メッセージ送受信を行ってみます Erlang VM :hear_after _say #PID <0.240.0> iex #PID <0.209.0>, spawn recieve send(‘Yo,Yo’) send(これは{#message} の受信に対する返信です) Yo,Yo これは’Yo,Yo’ の受信に対する返信です
  16. 16. 15 4.双方向のメッセージ送受信 メッセージ受信後に、送信元へメッセージを返却する、双方向の メッセージ送受信を行ってみます defmodule Pass do … def hear_after_say() do receive do { sender_pid, message } -> IO.puts( "受信メッセージ'#{message}'。返信をご確認ください。" ) send( sender_pid, { true, "これは'#{message}'の受信に対する返信です" } ) end hear_after_say() IO.puts( "------ hear_after_say() end ------" ) end … ※参照:第14章 P163
  17. 17. 16 4.双方向のメッセージ送受信:受信後の返信確認 受信プロセスにメッセージを送り、受信したメッセージが表示され るところまでは、これまでと同じですが、裏で返信をしています 自分宛に返ってきた返信を確認してみましょう iex> recompile() iex> pid = spawn( Pass, :hear_after_say, [] ) #PID<0.240.0> iex> send( pid, { self(), "Yo, Yo" } ) 受信メッセージ'Yo, Yo'。返信をご確認ください。 {#PID<0.209.0>, "Yo, Yo"} 返信先としての自分のPIDを渡します iex> receive do { true, message } -> IO.puts message end 「Yo, Yo」受信の返信 :ok ※参照:第14章 P163~164
  18. 18. 17 4.双方向のメッセージ送受信:返信確認② receive~を手入力する代わりに、confirm()を使って、自分 宛に返ってきた返信を確認することもできます なお、confirm()は、もし返信が無かった場合、ずっと待ち続け てしまいます iex> send( pid, { self(), "hear to me." } ) 受信メッセージ'hear to me.'。返信をご確認ください。 {#PID<0.209.0>, "hear to me."} iex> Pass.confirm() 受信メッセージ'「hear to me.」受信の返信' ------ confirm() end ------ :ok iex> recompile() iex> Pass.confirm … sendしないときは返信も無いため 待ち続けてしまう ※参照:第14章 P164
  19. 19. 18 4.双方向のメッセージ送受信:返信タイムアウト チェックから5秒間、返信無なら、タイムアウトさせます これで返信が無くても、待ち続けないようになります defmodule Pass do … def confirm() do receive do { true, message } -> IO.puts( "受信メッセージ'#{message}'。" ) after 5000 -> IO.puts( "Timeout..." ) end IO.puts( "------ confirm() end ------" ) … iex> recompile() iex> Pass.confirm Timeout... ------ confirm() end ------ :ok ※参照:第14章 P165
  20. 20. 19 5.Visualixirでプロセスの可視化
  21. 21. 20 5. Visualixirでプロセスの可視化 Visualixirは、Elixirのプロセスを可視化するツールです https://github.com/koudelka/visualixir 顕微鏡で見る微生物のような不思議なUIで可視化されます
  22. 22. 21 githubからリポジトリをcloneして、ビルドした後、Visualixirを 動かすPhoenixを起動します ブラウザで「http://localhost:4000/」を表示すると、 Visualixirが表示されます 5. Visualixirでプロセスの可視化 # git clone https://github.com/koudelka/visualixir # mix deps.get && mix compile && npm install npm@2.1.17 # elixir --sname visualixir --hidden -S mix phx.server [info] Running Visualixir.Endpoint with Cowboy using http://localhost:4000
  23. 23. 22 6.プロセス発生を観測してみる
  24. 24. 23 6.プロセス発生を観測してみる Passモジュールを繰り返しspawnするrepeat_spawn()にて、 Visualixirでプロセスが増殖していく様を観察してみます 別コンソールで、repeat_spawn()を以下のように起動し、 Visualixir上でプロセスが増える様を見てみましょう iex> spawn( Pass, :repeat_spawn, [ 1 ] ) defmodule Pass do … def repeat_spawn( count ) do spawn( Pass, :sample_process, [ 0 ] ) Process.sleep( 500 ) l_count = count + 1 repeat_spawn( l_count ) end def sample_process( count ) do Process.sleep( 100 ) l_count = count + 1 sample_process( l_count ) end プロセスを生成し続けるため、 再帰呼び出し 生成されたプロセスは無限ループ で生存させ続ける
  25. 25. 24 6.プロセス発生を観測してみる より高速にプロセスを増殖させてみましょう 別コンソールで、repeat_spawn_nosleep()を起動すると、 アッと言う間にVisualixir上がプロセスで埋め尽くされるのですが、 その状態でも、PCはさほど重くなっていないことが驚きです iex> spawn( Pass, :repeat_spawn_nosleep, [ 1 ] ) defmodule Pass do … def repeat_spawn_nosleep ( count ) do spawn( Pass, :sample_process, [ 0 ] ) l_count = count + 1 l_rem = rem( l_count, 10 ) if l_rem == 0 do :timer.sleep( 1 ) end repeat_spawn_nosleep( l_count ) end 1/10msecのsleep
  26. 26. 25 7.マルチコア/クラウド時代のプロセス指向
  27. 27. 26 7.マルチコア/クラウド時代のプロセス指向 今回は、Elixirのプロセスについてご説明しました 並行分散のベースとなる、プロセスの生成と通信による組み立て が「そこまで難しく無いかも?」と思っていただけたら、この入門と しては大成功です 今後ますますマルチコアCPU/クラウドでの性能upが求められる のに対し、「いかに並行分散が簡単にスラスラ書けるか?」という 点は、アプリ開発において最も重要となるでしょう Elixirは、オブジェクトのようにプロセスを気軽に作り、通信も簡単 なので、「プロセス指向」のプログラミングにたやすくシフトできます こうした機会をうまく捉え、仕事でも趣味でも、プログラミングライフ をエンジョイしてください!
  28. 28. 27 ご清聴ありがとうございます

×