Concurrency Elixir-受监督的进程似乎会阻止程序执行

Concurrency Elixir-受监督的进程似乎会阻止程序执行,concurrency,functional-programming,erlang,elixir,otp,Concurrency,Functional Programming,Erlang,Elixir,Otp,写一些小实验来熟悉这门语言,但是遇到了一个问题,我猜这是一个基本问题 我有一个简单的主管,有3个简单的工人: def init do Supervisor.start_link( [ worker(__MODULE__, [:"process-1"], [function: :test, id: :"p-1"]), worker(__MODULE__, [:"process-2"], [function: :test, id: :"

写一些小实验来熟悉这门语言,但是遇到了一个问题,我猜这是一个基本问题

我有一个简单的主管,有3个简单的工人:

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”进程链时,所有三个(或无论多个)进程都会同时启动,并将控制权返回给iex shell,这样我就可以从命令行发送已注册的进程消息

目前,我的意图是创建一个OTP主管,运行并注册三个(或任意多个)worker进程,并将它们附加到主管,发送一条简单消息以杀死给定的worker,然后让主管重新启动它


我做错了什么?

问题在于
函数:
您作为工作规范的一部分提供的功能没有达到OTP的预期

start函数必须创建并链接到子进程,以及 应返回{ok,Child}或{ok,Child,Info},其中Child是的pid 子进程和信息是一个被 主管

您的代码不会产生子循环,而是进入接收循环。您也许可以使用Elixir的
任务
模块来执行类似于您希望的操作:

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
可能是更好的选择