为什么我在启动 child 时会从这个一层深的 OTP 树中得到错误?

Why do I get an error from this one level deep OTP tree when I start the child?

现在,当我执行以下操作时,我从 start_child 收到错误状态:

{_, pid} = NTree.start_link
{_, cid} = Supervisor.start_child(pid, [])
# {:error, #<PID.0.91.0>}

这是为什么?我可以向它发送 "hello world" 之类的消息,并通过 IO.inspect 取回打印的消息。这意味着据我所知,这个过程是 运行。

defmodule NTree do
  # this will be the top line supervisor
  use Supervisor

  def start_link, do: Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)

  def init(:ok) do
    children = [
      worker(TreeWorker, [], restart: :temporary)
    ]

    supervise(children, strategy: :simple_one_for_one)
#   {:ok,
#   {{:simple_one_for_one, 3, 5},
#    [{TreeWorker, {TreeWorker, :start_link, []}, :temporary, 5000, :worker,
#      [TreeWorker]}]}}
  end

  def start_worker(supervisor) do
    persister = Supervisor.start_child(supervisor, [])
  end

end

defmodule TreeWorker do
  def start_link do
    spawn(fn -> loop end)
  end

  def loop do
    receive do
      :stop -> :ok

      msg ->
        IO.inspect msg
        loop
    end
  end
end

Process.info(cid) 产量:

[current_function: {TreeWorker, :loop, 0}, initial_call: {:erlang, :apply, 2},
 status: :waiting, message_queue_len: 0, messages: [], links: [],
 dictionary: [], trap_exit: false, error_handler: :error_handler,
 priority: :normal, group_leader: #PID<0.26.0>, total_heap_size: 233,
 heap_size: 233, stack_size: 1, reductions: 141,
 garbage_collection: [min_bin_vheap_size: 46422, min_heap_size: 233,
  fullsweep_after: 65535, minor_gcs: 0], suspending: []]

工人的启动函数必须 return {:ok, pid} 才能成功。 TreeWorker.start_link/0 return 仅 pid。您可以通过 returning {:ok, pid}:

来解决这个问题
defmodule TreeWorker do
  def start_link do
    {:ok, spawn(fn -> loop end)}
  end
  ...
end
iex(1)> NTree.start_link
{:ok, #PID<0.89.0>}
iex(2)> NTree.start_worker(NTree)
{:ok, #PID<0.91.0>}