Elixirの対話モードで並行性の動作を確認してみた

# 概要
Elixirの対話モードで並行性の動作を確認してみました。以下のページを参考にしました。

https://elixirschool.com/ja/lessons/intermediate/concurrency

# 対話モードで実行
以下のコマンドを実行しました。
```
$ iex
Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]

Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> defmodule Example do
...(1)> def add(a, b) do
...(1)> IO.puts(a + b)
...(1)> end
...(1)> end
{:module, Example,
 <<70, 79, 82, 49, 0, 0, 5, 20, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 154,
   0, 0, 0, 17, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:add, 2}}
iex(2)> Example.add(2, 3)
5
:ok
iex(3)> spawn(Example, :add, [2, 3])
5
#PID<0.117.0>
iex(4)> defmodule Example do
...(4)> def listen do
...(4)> receive do
...(4)> {:ok, "hello"} -> IO.puts("World")
...(4)> end
...(4)> listen()
...(4)> end
...(4)> end
warning: redefining module Example (current version defined in memory)
  iex:4

{:module, Example,
 <<70, 79, 82, 49, 0, 0, 5, 76, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 155,
   0, 0, 0, 16, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:listen, 0}}
iex(5)> pid = spawn(Example, :listen, [])
#PID<0.130.0>
iex(6)> send pid, {:ok, "hello"}
World
{:ok, "hello"}
iex(7)> send pid, :ok
:ok
iex(8)> defmodule Example do
...(8)> def explode, do: exit(:kaboom)
...(8)> end
warning: redefining module Example (current version defined in memory)
  iex:8

{:module, Example,
 <<70, 79, 82, 49, 0, 0, 4, 216, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 153,
   0, 0, 0, 16, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:explode, 0}}
iex(9)> spawn(Example, :explode, [])
#PID<0.140.0>
iex(10)> spawn_link(Example, :explode, [])
** (EXIT from #PID<0.106.0>) shell process exited with reason: :kaboom

Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> defmodule Example do
...(1)> def explode, do: exit(:kaboom)
...(1)> def run do
...(1)> Process.flag(:trap_exit, true)
...(1)> spawn_link(Example, :explode, [])
...(1)> receive do
...(1)> {:EXIT, _from_pid, reason} -> IO.puts("Exit reason: #{reason}")
...(1)> end
...(1)> end
...(1)> end
warning: redefining module Example (current version defined in memory)
  iex:1

{:module, Example,
 <<70, 79, 82, 49, 0, 0, 7, 152, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 1, 4, 0,
   0, 0, 28, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:run, 0}}
iex(2)> Example.run
Exit reason: kaboom
:ok
iex(3)> defmodule Example do
...(3)> def explode, do: exit(:kaboom)
...(3)> def run do
...(3)> {pid, ref} = spawn_monitor(Example, :explode, [])
...(3)> receive do
...(3)> {:DOWN, _ref, :process, _from_pid, reason} -> IO.puts("Exit reason: #{reason}")
...(3)> end
...(3)> end
...(3)> end
warning: redefining module Example (current version defined in memory)
  iex:3

warning: variable "pid" is unused (if the variable is not meant to be used, prefix it with an underscore)
  iex:6: Example.run/0

warning: variable "ref" is unused (if the variable is not meant to be used, prefix it with an underscore)
  iex:6: Example.run/0

{:module, Example,
 <<70, 79, 82, 49, 0, 0, 7, 148, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 243,
   0, 0, 0, 26, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:run, 0}}
iex(4)> Example.run
Exit reason: kaboom
:ok
iex(5)> {:ok, agent} = Agent.start_link(fn -> [1, 2, 3] end)
{:ok, #PID<0.174.0>}
iex(6)> Agent.update(agent, fn (state) -> state ++ [4, 5] end)
:ok
iex(7)> Agent.get(agent, &(&1))
[1, 2, 3, 4, 5]
iex(8)> Agent.start_link(fn -> [1, 2, 3] end, name: Numbers)
{:ok, #PID<0.178.0>}
iex(9)> Agent.get(Numbers, &(&1))
[1, 2, 3]
iex(10)> defmodule Example do
...(10)> def double(x) do
...(10)> :timer.sleep(2000)
...(10)> x * 2
...(10)> end
...(10)> end
warning: redefining module Example (current version defined in memory)
  iex:10

{:module, Example,
 <<70, 79, 82, 49, 0, 0, 5, 52, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 154,
   0, 0, 0, 17, 14, 69, 108, 105, 120, 105, 114, 46, 69, 120, 97, 109, 112, 108,
   101, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:double, 1}}
iex(11)> task = Task.async(Example, :double, [2000])
%Task{
  owner: #PID<0.143.0>,
  pid: #PID<0.190.0>,
  ref: #Reference<0.1258009529.3075473412.92097>
}
iex(12)> Task.await(task)
4000
iex(13)> 
```

# まとめ
何かの役に立てばと。