elixir - spawn/1 和 spawn/3 的区别

标签 elixir

我相信我在某处读到使用 spawn/1 之间存在差异和 spawn/3谈到热重载,但我找不到有关该主题的任何完整信息。所以我想知道是否真的有区别,如果有,那是什么?一些例子会很棒。谢谢你。

最佳答案

两者的区别在于spawn/1进行本地函数调用,而 spawn/3进行“完全合格”的函数调用。

当您加载模块的新版本时,旧版本仍然保留,并且在旧版本中执行的任何进程都会继续这样做。异常(exception)情况是进程执行“完全限定”的函数调用,包括模块名称:在这种情况下,始终使用最新版本的代码。

例如,使用此模块:

defmodule Foo do

  def start_loop do
    spawn(fn -> loop end)
  end

  def loop do
    receive do
      :foo ->
        spawn &print_foo/0
        loop
      :reload ->
        Foo.loop
    end
  end

  def print_foo do
    IO.puts "foo 1"
  end
end

我们可以启动一个进程,每次发送:foo对它来说,它会产生另一个打印 foo 1 的进程。 :
iex(1)> c("foo.ex")
[Foo]
iex(2)> p = Foo.start_loop
#PID<0.68.0>
iex(3)> send p, :foo
foo 1
:foo
iex(4)> send p, :foo
foo 1
:foo

现在,如果我们修改模块以打印 foo 2相反,重新编译并重新加载它,没有立即改变:
iex(5)> c("foo.ex")       
warning: redefining module Foo (current version loaded from Elixir.Foo.beam)
  foo.ex:1

[Foo]
iex(6)> send p, :foo
foo 1
:foo

只有当我们通过对模块进行完全限定的调用来告诉进程“重新加载”时,我们才能获得新版本:
iex(7)> send p, :reload
:reload
iex(8)> send p, :foo   
foo 2
:foo

当然,如果你使用 spawn/1使用只进行完全限定调用的函数,差异就消失了:
spawn(fn -> Foo.print_foo end)

关于elixir - spawn/1 和 spawn/3 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39089547/

相关文章:

database - 如何验证映射字段在 Ecto 模型(而不是 Controller )中是否具有特定键?

dynamic - Elixir - 通过字符串名称调用模块上的方法

elixir - 如何使用加载的关联序列化/反序列化 Ecto 模型?

elixir - Elixir中的串联数组

elixir - 获取指定索引对象时出错

SSL: :certify: ssl_handshake.erl:1507: fatal error :证书过期

mysql - 在 Ecto/Phoenix 中用微秒断言时间戳等于 mysql 数据库值

networking - {active, false}、{active, true} 和 {active, once} 有什么区别?

datetime - 如何在 Elixir 中模拟当前时间

elixir - 如何编写在日期时间字段上执行 group_by MONTH 的 Ecto 查询