【问题标题】:After a spawned Elixir process crashes, no other processes are spawned在生成的 Elixir 进程崩溃后,不会生成其他进程
【发布时间】:2018-07-17 21:00:54
【问题描述】:

在我的程序中,读取 CSV 文件的每一行后,都会生成一个新进程来下载该图像并将其保存到文件系统:

defmodule Downloader.CLI do
  alias Downloader.Parser
  alias Downloader.Getter

  def main(_args \\ []) do
    Enum.map(Parser.run, fn(line) ->
       line -> handle_download(line)
    end)
  end

  defp handle_download({ :ok, %{ "image_id" => image_id } }) do
    pid = spawn(Getter, :run, [])
    send(pid, {self(), image_id})

    receive do
      :ok -> nil
      err -> IO.inspect(err)
    end
  end
end

如果此 CSV 文件有 1000 个图像,则在 VM 中创建了 1000 个不同的 elixir 进程。但是,如果这些进程中只有一个抛出异常,则没有其他进程继续。也就是说,可执行文件不会冻结,但不会下载其他图像。

为什么会这样?如果它们彼此独立,为什么其他进程不能继续执行?我想错过一些简单的东西,但我在其他任何地方都找不到。

【问题讨论】:

    标签: erlang elixir


    【解决方案1】:

    问题receive do 等待一条永远不会到达的消息。

    这是一步一步发生的:

    1. spawn 创建进程 pid
    2. 进程 pid 在向初始进程发送回消息之前崩溃
    3. 初始进程卡在接收函数中:它正在等待消息。只要没有消息发送,一切都会被搁置。 Enum.map 将不会在下载后启动。

    为了说明这个问题,在 iex 中运行以下脚本:

    Process.send_after(self(), "Hi Luis", 30000)
    receive do
        mess -> IO.inspect mess
    end
    

    您将在 30 秒后收到"Hi Luis",在这 30 秒内,您的 iex 将等待消息,因为它是同步的。

    解决方案:确保始终发回消息,例如使用Process.monitor/1Supervisor

    defmodule Downloader.CLI do
      alias Downloader.Parser
      alias Downloader.Getter
    
      def main(_args \\ []) do
        Enum.map(Parser.run, fn(line) ->
           line -> handle_download(line)
        end)
      end
    
      defp handle_download({ :ok, %{ "image_id" => image_id } }) do
        pid = spawn(Getter, :run, [])
        Process.monitor(pid)
        send(pid, {self(), image_id})
    
        receive do
          :ok -> nil
          err -> IO.inspect(err)
        end
        flush   # To avoid having a Down message ending prematurely next download 
      end
    end
    

    【讨论】:

    • 那是缺失的一点!我认为仅仅使用spwan 我已经是异步的,但我不是。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    相关资源
    最近更新 更多