啟動行程雖然簡單,但要管理它的狀態和行為,卻可能變得非常複雜。Agent模組是一層抽象,方便我們在 Elixir 行程中管理共享狀態。
使用Agent模組的函式時,通常會把與代理相關的函式封裝在同一個模組裡。
# A simple use of agent processes to represent a counter
defmodule Counter do
def start_link(initial_value) do
Agent.start(fn -> initial_value end)
end
def value(pid) do
Agent.get(pid, & &1)
end
def increment(pid) do
Agent.update(pid, &(&1 + 1))
end
end
要不要使用Agent模組,甚至要不要用到多個行程,取決於你想用資料建立什麼樣的關係。當共享狀態必須被多個行程使用時,代理行程就很有用。
很多時候,更好的做法是不要另外開一個行程,而是在函式裡用行程內的變數來保存狀態。也要小心,別盲目把它們當成全域變數,因為它們可能被其他行程操作,進而產生競爭條件或難以追蹤的錯誤。
如果決定使用代理行程,目標應該是保存簡單的狀態,並把對代理行程的呼叫封裝在模組裡,讓這些呼叫有條理。
如果有一項耗時的工作要在另一個行程中完成,可以考慮使用任務行程(使用Task)。如果確定某個行程需要保存狀態並執行行為,則可以考慮使用 GenServer 行程(使用GenServer)。