【问题标题】:gen_fsm initial state, sending event to it on spawninggen_fsm 初始状态,在生成时向其发送事件
【发布时间】:2011-05-09 00:28:30
【问题描述】:

如果我想在生成 gen_fsm 时始终将事件发送到它的初始状态,我应该将该函数调用放在哪里?就在 start_link 之后或从首先调用 start_link 的进程开始。这里有什么最佳做法吗?

【问题讨论】:

    标签: erlang erlang-otp


    【解决方案1】:

    如果你只是想在启动 FSM 后改变它的状态,你可以简单地为你的状态机实现 init 函数:

    阅读自:http://www.erlang.org/doc/man/gen_fsm.html#Module:init-1

    每当 gen_fsm 开始使用 gen_fsm:start/3,4 或 gen_fsm:start_link/3,4,这个函数 被新进程调用 初始化。

    Args 是提供给 启动函数。

    如果初始化成功,则 函数应该返回 {ok,StateName,StateData}, {ok,StateName,StateData,Timeout} 或 {ok,StateName,StateData,休眠}, 其中 StateName 是初始状态 name 和 StateData 初始状态 gen_fsm 的数据。

    此外,使用 init 函数,您可以确定这两个函数(start_link 和 init)的原子性。他们都会成功或失败。

    【讨论】:

    • 主要不是我想改变状态,我想在初始状态执行代码,然后切换到下一个状态。我是否应该让 init 函数返回超时值 0,如下面的答案中建议的那样?
    • 当您使用 start_link 函数启动 gen_fsm 时,状态将传递给 init 函数。然后,您可以在那里执行您的代码,并在需要时更新状态,该状态将在 gen_fsm 生命周期的剩余时间内可用。
    【解决方案2】:

    我认为从调用 FSM 启动函数的进程发送第一个事件是正确的。或者从 init/1 返回 timeout = 0 并在初始状态下处理 'timeout' 事件。

    另一方面,如果您的 gen_fsm 是一个已注册的进程,则可以进行竞争。如果是这种情况,我会在注册之前从 init/1 向 gen_fsm 进程 PID 发送消息。

    【讨论】:

    • init 函数中的超时值 0 会导致潜在的竞争条件吗?还是您的意思是从启动 FSM 的进程调用可能会导致竞争条件?
    • 如果在 start_link 返回之前注册了 FSM 进程,它们都会导致竞争条件。
    猜你喜欢
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 2014-07-13
    相关资源
    最近更新 更多