Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/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 - Fatal编程技术网

Elixir 正确等待进程完成

Elixir 正确等待进程完成,elixir,Elixir,目前我有这样的想法: 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

目前我有这样的想法:

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_链接,它向使用者发送数据流,所有这些都发生在一个mix任务中,因此如果我不添加receive do,一旦mix消失,它也会终止子进程,就像我从iex-S mix shell运行它一样

flow
... some producer consumer in the middle
|> Flow.into_specs(consumer)
问题是,当流为空(是一个有限流)时,工作者似乎不会死亡,接收不会被触发,有没有其他方法来实现这一点

编辑:

我甚至不需要
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

但是,当工作者启动一个流时,如果我不使用
receive do
等待,它会在我执行任务时立即消失,因此可能这就是问题所在。

根据以下文档:

如果调用
process.monitor/1
时进程已停止,则会立即发送
:DOWN
消息

也就是说,当
为空时,
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\u ref\u某处\u ets\u或\u agent\u或\u which/1
和相应的
retrieve\u ref/0
将很容易实现。

当流为空时,它应该立即返回,比您进入
receive
的过程要快。你能检查一下进程的进程吗?监视器(工作者)返回的进程吗?ref只是一个pid,工作者是这样启动的;{:好的,worker}=worker.start_link([]),然后ref=Process.monitor(worker)您如何预先定义msg?第4行和第6行中的:normal和:DOWN?模式匹配可以区分这两种模式。顺便说一句,我正在测试它(使用:ets),但它并没有停止进程,我的意思是,退出混合任务,在所有有限流被消耗后它会卡住。实际上,我正在调试这个:接收做某事->需要IEx;IEx.pry结束并且没有到达任何对象,如果流在结束时没有发送任何消息,则不会触发