2015-02-27 2 views
0

Это как вы избегаете гонки?Избегайте состояния гонки в erlang

-module(b). 
-export([my_spawn/1]). 



my_spawn(Func) -> 
    Pid = spawn(listener()), 
    Pid ! {self(), spawn, Func}, 
    receive 
     {From, Desired_Pid} -> Desired_Pid 
    end. 




listener() -> 

    receive 
     {From, spawn, Func} -> 
     {Pid,Ref} = spawn_monitor(Func), 
     From ! {self(), Pid}, 
     receive 
      {'DOWN',Ref, process, _, _} -> io:format("I lived for [calculated how long i lived]") 
     end 
    end. 

То, что я пытаюсь достичь здесь

A = spawn(proc), 
monitor(process,A). 

Однако может умереть прежде, чем выполняет второй линии.

+0

Возможный дубликат [erlang race condition of spawn and receive] (http://stackoverflow.com/questions/28579698/erlang-race-condition-of-spawn-and-receive) – Pascal

ответ

3

Если вы породите процесс и он умирает как раз перед тем, как создать свой монитор, вы все равно получить DOWN сообщений:

1> Pid = spawn(erlang,now,[]). 
<0.35.0> 
2> is_process_alive(Pid). 
false 
3> monitor(process, Pid). 
#Ref<0.0.0.86> 
4> flush(). 
Shell got {'DOWN',#Ref<0.0.0.86>,process,<0.35.0>,noproc} 

В этой оболочке сессия показывает, мы первый нерест намеренно недолгий процесс, и мы используем is_process_alive, чтобы убедиться, что он мертв. Затем мы создаем монитор для процесса, а затем очищаем очередь сообщений оболочки и видим, что он действительно получил сообщение DOWN для уже умершего процесса.

+0

Так что нет необходимости идти через всю суету. Я читал в книге Джо Армстронга, что если процесс умирает до того, как мы создадим ссылку/монитор, функция on_exit (которая является просто потехой, оцененной после того, как процесс получит «DOWN») не будет работать должным образом. Я что-то пропустил здесь или там были какие-то обновления, сделанные erlang, чтобы сделать это замечание бесполезным? – Bula

+0

Ссылки и мониторы - это две разные вещи. В частности, вам нужно избегать условий гонки между 'spawn' и' link' через 'spawn_link', учитывая, что' link' по умолчанию заставляет оба связанных процесса умирать, если они умирают. Если процесс A умирает до того, как процесс B связывается с ним, B не умрет и не получит сообщение о выходе, если оно улавливает выходы. Как вы можете видеть из моего ответа, мониторы ведут себя по-разному. –