长生不老药的“丢失”工艺流程 [英] Elixir "Losing" Processes

查看:104
本文介绍了长生不老药的“丢失”工艺流程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我创建文件 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆