【问题标题】:Avoiding a race condition in erlang在 erlang 中避免竞争条件
【发布时间】:2015-02-28 03:10:18
【问题描述】:

这是避免竞争条件的方法吗?

-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).

但是 A 可能会在第二行执行之前死掉。

【问题讨论】:

标签: erlang race-condition


【解决方案1】:

如果您生成了一个进程并且它在您创建监视器之前终止,您仍然会收到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}

正如这个 shell 会话所示,我们首先故意生成一个短暂的进程,然后使用is_process_alive 来验证它是否已经死亡。然后,我们为该进程创建一个监视器,然后我们刷新 shell 的消息队列,并看到它确实收到了已死进程的 DOWN 消息。

【讨论】:

  • 所以没有必要经历所有的喧嚣。我在 Joe Armstrong 的书中读到,如果进程在我们创建链接/监视器之前终止,那么 on_exit 函数(这只是一个有趣的评估在进程收到 DOWN 后)将无法按预期工作。我在这里遗漏了什么还是对 erlang 进行了一些更新以使此评论变得无用?
  • 链接和监视器是两个不同的东西。特别是,您确实需要通过spawn_link 避免spawnlink 之间的竞争条件,因为link 默认情况下会导致两个链接进程在任何一个死亡时都死亡。如果进程 A 在进程 B 链接到它之前就死了,那么 B 不会死,如果它正在捕获退出,它也不会收到任何退出消息。但是,正如您从我的回答中看到的那样,监视器的行为有所不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 2010-09-25
  • 2010-09-25
  • 2019-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多