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

标签 concurrency functional-programming erlang elixir erlang-otp

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

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

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

“:测试”看起来像这样:

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 主管,运行并注册三个(或任意多个)工作进程并将它们附加到主管,发送一条简单消息以杀死给定的工作人员,然后让主管重新启动

我做错了什么?

最佳答案

问题是 function: 你作为 worker 规范的一部分给出的没有做 OTP 期望的事情。

来自 http://www.erlang.org/doc/man/supervisor.html

The start function must create and link to the child process, and should return {ok,Child} or {ok,Child,Info} where Child is the pid of the child process and Info an arbitrary term which is ignored by the supervisor.

您的代码不会产生子代,但会进入接收循环。您也许可以使用 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 可能是更好的选择。

关于concurrency - Elixir - 受监督的进程似乎会阻止程序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29500664/

相关文章:

linux - Linux 线程中的文件段/节/记录锁

python - Tornado 中的队列和 ProcessPoolExecutor

oop - 您认为函数式语言适合具有大量业务规则但计算量很少的应用程序吗?

java - ConcurrentLinkedHashMap.Builder如何处理删除和获取?

concurrency - 我如何在预览中构造带注释的 mainactor 的 swiftui 类

functional-programming - 为什么在函数定义中进行自调用是合法的,但对于值是非法的?

scala - 在 FP 中处理 POST 的*正确*方法是什么?

types - 具有类型和值限制以及默认值的 Erlang 记录

rest - 为 Cowboy REST API 启用 CORS

Erlang:如何处理长时间运行的 init 回调?