Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 工人在主管启动后退出_Elixir_Gen Server_Erlang Supervisor - Fatal编程技术网

Elixir 工人在主管启动后退出

Elixir 工人在主管启动后退出,elixir,gen-server,erlang-supervisor,Elixir,Gen Server,Erlang Supervisor,我正在尝试在mix.exs中调用应用程序模块的主管中启动以下工作人员 像这样 defmodule AppStarter do import Supervisor.Spec def start(_type,_args) do children=[ worker(TPMod1,[],[]), worker(TPMod2,[],[]) ] opts=[strategy: :one_for_one, name: HelloVisor] Su

我正在尝试在mix.exs中调用应用程序模块的主管中启动以下工作人员

像这样

defmodule AppStarter do
import Supervisor.Spec
def start(_type,_args) do
    children=[
        worker(TPMod1,[],[]),
        worker(TPMod2,[],[])
    ]
    opts=[strategy: :one_for_one, name: HelloVisor]
    Supervisor.start_link(children,opts)
end


end
我的一个模块是GenServer,另一个模块是一个简单的监听过程

defmodule TPMod1 do

def start_link() do
 IO.puts "started TPMod1"
 listen()
end



def listen() do
  receive do
    _ -> :ok
  end
  listen()
end

 def child_spec(opts) do
      %{
        id: __MODULE__,
        start: {__MODULE__, :start_link, []},
        type: :worker,
        restart: :permanent,
        shutdown: 500
      }
    end


end
问题是它卡住了,无法启动worker 2
TPMod2
我在
TPMod1
start\u link()中尝试过

但这给了我这个

**(Mix)无法启动应用程序tproject:AppStarter。启动(:normal,[])返回错误:关机:无法启动 启动子项:TPMod1 **(退出)%Task{owner:#PID,PID:#PID,ref:#Reference}


我可以让它成为GenServer,让它工作,但我们如何才能开始一个简单的工人?为什么主管不重新启动它?不是无限,而是有时?它至少应该尝试重新启动并失败。如果有其他改进,请提出建议。

主管希望孩子们返回
{:ok,pid}
:ignore
{:error,reason}

它挂起是因为当主管在您的工作人员上运行
start\u link
函数时,它会(像他自己一样)执行
listen
,这会设置一个
receive
块,因此它会卡在那里。当您使用gen_*模块的
start_链接
和friends时,它负责生成、正确返回等

在您的情况下,您可以切换:

def start_link() do
 IO.puts "started TPMod1"
 listen()
end
致:


这样就可以了。

酷!因此,始终使用gen_u*而不是简单的繁殖和返回是一种良好的做法吗?@YugandharChaudhari我认为在99%的常规情况下,没有理由不使用现有的OTP行为,因为它满足了主管等的期望,而对于原始流程,如果你想成为OTP,就必须实施这些行为。有时gen_服务器太多(但任何有点结构的进程都很适合),您可以使用类似于任务的东西(通过不同的模式,如async_nolink等)很好地适应其他OTP行为,例如gen_服务器,可以从内部生成,也可以从外部等待,等等。这当然取决于……酷!因此,始终使用gen_*[行为]而不是简单的繁殖和返回,这是一种好的做法吗?--这不仅仅是良好的实践,也是唯一的实践。有一次,我试图弄清楚如何使用主管启动任意进程,在erlang中进行了大量的挖掘,终于弄清楚不能使用主管启动任意进程。主管期望其启动的流程是OTP
应用程序
,…。这意味着工作人员必须定义某些功能,并且这些功能必须返回主管期望的某些值…这就是主管能够与工作人员通信的方式。这里有一些更多的信息:另外:
Supervisor.Spec——此模块已弃用。改用“主管”模块中概述的新子规范。
def start_link() do
 IO.puts "started TPMod1"
 listen()
end
def start_link() do
 pid = spawn(__MODULE__, :listen, [])
 {:ok, pid}
end