【问题标题】:Correctly waiting for process to finish正确等待进程完成
【发布时间】:2019-01-30 18:10:18
【问题描述】:

目前我有这样的事情:

ref = Process.monitor(worker)

receive do
  {:DOWN, ^ref, :process, ^worker, :normal} ->
    IO.puts("Normal exit from #{inspect(worker)}")

  {:DOWN, ^ref, :process, ^worker, msg} ->
    IO.puts("Received :DOWN from #{inspect(worker)}")
end

那个工人有一个 start_link 它将数据流发送到消费者,所有这一切都发生在一个混合任务中,所以如果我不添加接收,一旦混合死亡,它也会杀死子进程,同样就像我从 iex -S mix shell 运行它一样。

flow
... some producer consumer in the middle
|> Flow.into_specs(consumer)

问题是,当流为空时(是一个有限流),worker 似乎没有死,接收不会被触发,还有其他方法可以实现吗?

编辑:

用我什至不需要receive do的虚拟进程进行测试

defmodule Mix.Tasks.Stuff do


  def run([]) do
    {:ok, worker} = Worker.start_link([])
  end
end

defmodule Worker do

  def start_link([]) do
    Enum.map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], fn number ->
      IO.puts "COUNTING"
      Process.sleep(1000)
      IO.puts "-----------"
    end)
  end
end

但是当工作人员启动 Flow 时,如果我不等待 receive do,它会在我执行任务时立即死亡,所以也许这就是问题所在。

【问题讨论】:

  • 当流为空时,它应该立即返回,比您的进程转到receive 更快。请问|> IO.inspectProcess.monitor(worker)返回什么?
  • ref 只是一个 pid
  • worker是这样启动的; {:ok, worker} = Worker.start_link([]) 然后 ref = Process.monitor(worker)

标签: elixir


【解决方案1】:

根据Process.monitor/1上的文档:

如果在调用Process.monitor/1 时进程已经死亡,则立即传递:DOWN 消息。

也就是说,当Flow 为空时,receive do:DOWN 消息设置处理程序发送之后。为了处理这种情况,应该在开始监视进程之前交换调用并准备消息处理程序

receive do
  {:DOWN, ref, :process, ^worker, msg} ->
    case [retrieve_ref(), msg] do
      [^ref, :normal] ->
        IO.puts("Normal exit from #{inspect(worker)}")
      [^ref, msg] ->
        IO.puts("Received :DOWN from #{inspect(worker)}")
    end
end

ref = Process.monitor(worker)
store_ref_somewhere_ets_or_agent_or_whatever(ref)

我认为store_ref_somewhere_ets_or_agent_or_whatever/1 和各自的retrieve_ref/0 很容易实现。

【讨论】:

  • 你会如何预先定义味精?它可以是 :normal 和 :DOWN?
  • 第 4 行和第 6 行中的模式匹配区分这两者。可以是:normal, :noproc, and :noconnection顺便说一句。
  • 我正在测试它(使用 :ets),但它不会停止进程,我的意思是,退出混合任务,在消耗完所有有限流后它会卡住
  • 其实我在调试这个:receive do something -> require IEx; IEx.pry 结束,什么都没有到达,它没有被触发
  • 就像Flow在完成时没有发送任何消息
猜你喜欢
  • 1970-01-01
  • 2010-11-06
  • 2011-11-09
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多