虽然启动一个进程很容易,但管理它的状态和行为可能会变得非常复杂。Agent模块是一种抽象,用来方便地管理 Elixir 进程中的共享状态。
使用Agent模块的函数时,通常会把与 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模块,或者是否要使用多个进程,取决于需要用数据建模的关系。当共享状态需要被多个进程使用时,_Agent 进程_就很有用。
很多时候,更好的做法是不使用单独的进程,而是在函数内用一个进程内的变量来保存状态。同时也要注意,不要盲目地把它们当作全局变量,因为它们可能被其他进程操作,从而产生竞态条件或难以追踪的错误。
如果选择使用_Agent 进程_,目标应该是保存简单的状态,把对_Agent 进程_的调用封装在同一个模块中,以便组织这些调用。
如果需要在另一个进程中完成开销很大的工作,应该考虑使用_Task 进程_(借助Task)。如果确定某个进程需要保存状态并执行行为,就应该考虑使用_GenServer 进程_(借助GenServer)。