2013-07-23 34 views
1

在向其發送消息/事件之前,Erlang中確保某個進程存在的最推薦方法是什麼?在我的情況下,我首先發生的消息開始處理,然後它仍然活着。雖然不斷通過進一步的消息,我第一次嘗試啓動過程中使用相同的名稱,以確保它啓動時,這樣的事情(使用gen_fsmsimple-one-for-one重啓場景):在發送消息時確保gen_fsm/gen_server進程存在

%% 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

你是對的,erlang:is_process_alive/1方法在這種情況下是無用的,因爲競爭條件。

你的例子是可行的,我幾次在野外看到它。請注意,它不保證該消息將被處理。爲了確保你需要監視你的接收器並從中得到確認。這是在gen_server:call/2中如何完成的。