【问题标题】:Elixir: cannot run :timer.tc in spawned process in elixir scriptElixir:无法在 Elixir 脚本的衍生进程中运行 :timer.tc
【发布时间】:2020-05-17 22:26:22
【问题描述】:

在 iex 控制台中可以正常工作:

iex(1)> spawn(fn -> :timer.tc(:timer, :sleep, [100]) |> elem(0) |> IO.puts end) #PID<0.106.0> 100603

但是当我在 .exs 脚本中放入完全相同的行 spawn(fn -&gt; :timer.tc(:timer, :sleep, [100]) |&gt; elem(0) |&gt; IO.puts end) 时 - 没有任何反应,根本没有输出。

这是为什么呢?如何并行测量函数的执行时间?

【问题讨论】:

  • 为什么需要并行呢?它应该如何工作?为什么this的方式不适合你?
  • @GuruStron 为什么 OP 需要并行执行完全超出了原始问题的范围。另外,基准测试和遥测有完全不同的应用,这个问题肯定更多是关于telemetry

标签: elixir


【解决方案1】:

脚本在打印之前退出并且你没有监控启动的进程,这会导致有点竞争条件。事实上,一切都按预期进行。确保您的脚本等待生成的进程完成(正确的方法是使用 Task,但这对于 PoC 来说是可以的:

# test.exs
spawn(fn ->
  :timer
  |> :timer.tc(:sleep, [100])
  |> elem(0)
  |> IO.puts()
end)
Process.sleep(1_000)

正确的解决方案:

# test.exs
task = Task.async(fn ->
  :timer
  |> :timer.tc(:sleep, [100])
  |> elem(0)
  |> IO.puts()
end)
Task.await(task) # this prevents ErlangVM from immediate exit

【讨论】:

  • 太好了,谢谢,这很有效 :) 现在我可以生成多个进程,保存到列表并在每个任务上运行 Task.await。
  • 当然可以。要等待几项任务,可以改用Task.yield_many/2
猜你喜欢
  • 1970-01-01
  • 2017-10-16
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
  • 1970-01-01
相关资源
最近更新 更多