写一些小实验,让我熟悉这门语言,但遇到了一个问题,我猜这是最基本的问题。
我有一个简单的主管,有三个简单的工人:
def init do
Supervisor.start_link(
[
worker(__MODULE__, [:"process-1"], [function: :test, id: :"p-1"]),
worker(__MODULE__, [:"process-2"], [function: :test, id: :"p-2"]),
worker(__MODULE__, [:"process-3"], [function: :test, id: :"p-3"])
],
strategy: :one_for_one
)
end":test“如下所示:
def test(name) do
flag(:trap_exit, true)
IO.puts "Testing: #{name} == #{inspect self}"
register(self, name)
receive do
{ :death } ->
IO.puts("I WOZ MURDERED!")
exit(self, "Ex process...")
{ :life } ->
IO.puts("#{inspect self} is listening...")
__MODULE__.test(name)
{ :EXIT, pid, reason } ->
IO.puts "REASON: #{inspect reason} - PROCESS: #{inspect pid}"
end
end这是编译的,但它只生成一个进程,并挂起/阻止iex。
相反,当我使用简单的‘spawn_link’‘ed’进程链时,所有三个进程(无论多多)都同时启动,并将控制返回到iex,这样我就可以从命令行发送已注册的进程消息。
现在,我的目的是创建一个OTP监控器,运行和注册三个(或多少个)工作者进程,并将它们附加到主管,发送一个简单的消息来杀死一个给定的工作人员,然后让主管重新启动它。
我做错了什么?
发布于 2015-04-07 21:13:43
问题是,作为工作人员规范的一部分,您提供的function:并不能满足OTP的要求。
来自http://www.erlang.org/doc/man/supervisor.html
开始函数必须创建子进程并链接到子进程,并且应该返回{ok,Child}或{ok,Child,Info},其中child是子进程的pid,Info是监控器忽略的任意项。
您的代码不生成子代码,而是进入接收循环。您也许可以使用Elixir的Task模块来做一些与您想要的类似的事情:
worker(Task, [__MODULE__, :test, [:"process-1"]], id: :"p-1"),
worker(Task, [__MODULE__, :test, [:"process-2"]], id: :"p-2"),
worker(Task, [__MODULE__, :test, [:"process-3"]], id: :"p-3")但是,如果您希望更多地了解OTP的功能,那么尝试实现自己的GenServer可能是一个更好的选择。
https://stackoverflow.com/questions/29500664
复制相似问题