长生不老药的“丢失”工艺流程 [英] Elixir "Losing" Processes
问题描述
如果我创建文件 loop.exs
:
Enum.each(1..40000, fn (n) -> spawn fn -> IO.puts(n) end end)
运行它,计算输出行数:
And run it, counting the lines of output:
elixir loop.exs | wc -l
在随后的运行中,我可能会看到预期的 40000
行,但可能看不到。在测试中,我已经看到 39752
, 39934
, 39673
等。这向我提示某些进程无法调用 IO.puts
,所以它们发生了什么,为什么不警告他们呢?丢失了,这是怎么回事?
And on subsequent runs, I may see the expected 40000
lines, but I might see less. In my tests, I've seen 39752
, 39934
, 39673
, etc. This suggests to me that certain processes aren't getting to call IO.puts
, so what is happening to them, why aren't I warned they've gone missing, and what am I doing wrong that is making this happen?
推荐答案
问题是脚本退出为一旦完成了在根级别评估表达式。由于生成过程是异步的,因此Elixir会在完成第40,000个生成过程后立即退出。您看到的行数是在生成第40,000个进程之前完成执行 IO.puts
的进程数。您可以通过在末尾添加一个:timer.sleep / 1
调用来验证这一点:
The problem is that the script is exiting as soon as it's done evaluating the expressions at the root level. Since spawning processes is asynchronous, Elixir quits as soon as it's done spawning the 40,000th process. The number of lines you're seeing is the number of processes that finished executing IO.puts
before the 40,000th process was spawned. You can verify this by adding a little :timer.sleep/1
call at the end:
Enum.each(1..40000, fn (n) -> spawn fn -> IO.puts(n) end end)
:timer.sleep(500)
有了这个,我总是得到4万行输出。 (如果最后一个 IO.puts
在产生最后一个进程的500毫秒内未执行,则此数字会减少。)
With this, I always get 40k lines of output. (This number will be less if the last IO.puts
isn't executed within 500 milliseconds of the last process being spawned.)
这篇关于长生不老药的“丢失”工艺流程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!