2016-08-22 3 views
3

Я считаю, что я где-то читал, что есть разница между использованием spawn/1 и spawn/3, когда дело доходит до горячей перезагрузки, но я не могу найти полную информацию по этому вопросу. Поэтому я задаюсь вопросом, есть ли на самом деле разница, и если да, то что это? Какой-то пример будет замечательным. Спасибо.Разница между spawn/1 и spawn/3

ответ

5

Разница между двумя заключается в том, что spawn/1 выполняет локальный вызов функции, а spawn/3 выполняет «полноценный» вызов функции.

Когда вы загружаете новую версию модуля, старая версия все еще хранится, и любой процесс, который выполнялся в старой версии, продолжает это делать. Исключением является то, что процесс выполняет «полный» вызов функции, включая имя модуля: в этом случае всегда используется самая новая версия кода.

Например, с этим модулем:

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) 
+0

Я не мог попросить лучшего объяснения, спасибо. – JustMichael