1

在向其发送消息/事件之前,在 Erlang 中确保某个进程存在的最推荐方法是什么?在我的场景中,我在第一次出现消息时开始处理,然后它保持活动状态。在继续传递更多消息的同时,我首先尝试使用相同的名称启动进程以确保它已启动,如下所示(使用gen_fsmsimple-one-for-one重新启动场景):

%% DeviceId - process name

heartbeat(ApplicationKey, DeviceId, Timeout) ->
    ensure_session_started(ApplicationKey, DeviceId, Timeout),
    gen_fsm:send_event(DeviceId, {heartbeat, Timeout}).

ensure_session_started(ApplicationKey, DeviceId, Timeout) ->
    case session_server_sup:start_child(ApplicationKey, DeviceId, Timeout) of
        {ok, _Pid} -> {ok, running};
        {error, {already_started, _}} -> {ok, running};
        {error, Error} -> erlang:throw({error, {failed_to_start_session, Error}})
    end.

我相信这个解决方案并不完美,可能会有一些开销,但仍然相信它比使用erlang:is_process_alive. 我对吗?任何想法如何改进它?

4

2 回答 2

4

你是对的, erlang:is_process_alive/1 方法在这种情况下是无用的,因为竞争条件。

你的例子是可行的,我在野外看到过几次。请注意,它不保证会处理该消息。为确保这一点,您需要监控您的接收器并从中获得确认。这是在 gen_server:call/2 中完成的。

于 2013-07-23T18:43:49.127 回答
2

使用gen_fsm:sync_send_event/2,3您可以将事件发送到您的 FSM 并等待响应。所以你可以告诉你的调用进程它的消息已经收到。

于 2013-07-24T07:32:24.267 回答