代码之家  ›  专栏  ›  技术社区  ›  user782220

使用计时器更改从退出派生进程接收的错误消息

  •  3
  • user782220  · 技术社区  · 12 年前

    在下文中,为什么一个错误消息以“异常退出”开头,而另一个以“异常错误”开头?

    1> spawn_link(fun ()-> exit(reason) end).
    ** exception exit: reason
    2> spawn_link(fun ()-> timer:sleep(1), exit(reason) end).
    <0.38.0>
    ** exception error: reason
    
    2 回复  |  直到 12 年前
        1
  •  2
  •   den'ver    12 年前

    这是答案 errors-and-processes

    1> link(spawn(fun() -> exit(reason) end)).
    ** exception exit: reason
    2> link(spawn(fun() -> timer:sleep(1000), exit(reason) end)).
    true
    ** exception error: reason
    

    异常退出-当进程在链接之前终止时

        2
  •  0
  •   RichardC    12 年前

    我很确定这是由于Erlangshell实现中的竞争条件所致。记住,shell也是另一个Erlang进程,它读取命令、解释命令、打印结果和循环。当您使用spawn_link时,新进程将链接到shell求值器进程,当新进程终止时,将向shell求值器程序发送退出信号(该程序也会因同样的原因崩溃并重新启动)。所有这些对于用户来说应该基本上是不可见的,但在某些情况下,实现细节可能会泄露出去。

    在第一种情况下,新进程被派生并开始运行,但会立即调用exit。在第二种情况下,它开始运行,休眠一毫秒,再次醒来,然后退出。这意味着shell求值器进程有足够的时间继续,打印spawn_link的结果Pid,并且当它从派生的进程获得退出信号时,它将请求更多的输入。评估者当前所在位置的差异导致退出原因以不同的方式打印(不知何故)。严格来说,我认为这是一个bug。

    进一步演示:

    1> spawn_link(fun ()-> timer:sleep(1), exit(reason) end), timer:sleep(1).
    ** exception exit: reason
    

    在这里,通过在生成新流程后休眠一毫秒,使解释代码运行更长时间,我们可以恢复原始行为。