Elixirにおけるプロセスについて
プロセスとは?
Elixirにおいて、全てのコードはプロセス内で実行されます 各プロセスは隔離されており、平行に動作します
各プロセスはメッセージパッシングによってやり取りします
プロセスの生成
spawnまたはspawn_link関数でプロセスを生成できます
code:elixir
pid = spawn fn -> :hello end
spawn_link
spawn_linkを使うと、現在のプロセスと生成されたプロセスがLinkします※後述
メッセージパッシング
sendとreceive関数を使って、プロセス間でメッセージを送受信できます
code:elixir
# self()で現在のプロセスのPIDを取得できます
ppid = self()
# send/2で指定したPIDのプロセスのメールボックスへメッセージを送信します
spawn_link fn -> send(ppid, {:message, "hello"}) end
# reveive/1で、現在のプロセスのメールボックスに、指定したパターンにマッチするメッセージが到着することを待機します
receive do
{:message, msg} -> msg
_ -> "won't be executed"
end # => "hello"
Agent
状態管理を抽象化したプロセス
code:elixir
# Agentを開始
{:ok, agent} = Agent.start_link fn -> %{} end
Process.alive?(agent) # => true
# Agent.updateで状態を更新できます
Agent.update(agent, fn map -> Map.put(map, :a, 1) end)
# Agent.getで状態を取得できます
Agent.get(agent, fn map -> map end) # => %{a: 1}
Agent.update(agent, fn map -> Map.put(map, :b, 2) end)
Agent.get(agent, fn map -> map end) # => %{a: 1, b: 2}
# Agentを停止します
Agent.stop(agent)
Process.alive?(agent) # => false
参考
Task
Monitor
Process.monitor(pid)でプロセスの停止等を監視できる
LinkとMonitorの違い
Linkは双方向
2つのプロセスをLinkさせた場合、一方がクラッシュすると、もう一方もクラッシュする
Monitorは単方向
監視元プロセスは、監視対象プロセスの終了、クラッシュ等の発生を知ることができる
参考
Supervisor
参考