O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
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
ご清聴ありがとうございます
Próximos SlideShares
Carregando em…5
×

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

986 visualizações

Publicada em

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

Publicada em: Engenharia
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

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 ご清聴ありがとうございます

×