是否有可能阻止同步函數(handle_call)等待不同模塊中的異步調用(handle_cast)?erlang混合同步和異步函數
即 如何才能使同步功能等待(即阻止),直到收到來自異步功能的特定「完成」消息? (然後才繼續執行) 這兩個模塊都遵循gen_server和gen_fsm行爲。
handle_info可以以某種方式使用嗎?
問候 /彼得
是否有可能阻止同步函數(handle_call)等待不同模塊中的異步調用(handle_cast)?erlang混合同步和異步函數
即 如何才能使同步功能等待(即阻止),直到收到來自異步功能的特定「完成」消息? (然後才繼續執行) 這兩個模塊都遵循gen_server和gen_fsm行爲。
handle_info可以以某種方式使用嗎?
問候 /彼得
這樣做是爲了節省掉參考發件人handle_call
,並在以後調用gen_server:reply
的方式。也就是說,當你通常寫你handle_call
功能是這樣的:
handle_call(foo, _From, State) ->
{reply, {ok, bar}, State}.
你會做這樣的事情:
handle_call(foo, From, State = #state{pending = Pending}) ->
NewState = State#state{pending = [From | Pending]},
{noreply, NewState}.
再後來,也許在handle_info
:
handle_info({bar_event, Data}, State = #state{pending = [Head | Tail]) ->
gen_server:reply(Head, {ok, Data}),
NewState = State#state{pending = Tail},
{noreply, NewState}.
這意味着當進程調用gen_server:call(Pid, foo)
時,它將阻塞,直到服務器進程收到{bar_event, Data}
,此時服務器將把事件中包含的數據返回給調用者。
我試圖通過在「堆棧」中存儲關於調用者的信息來簡化示例,因此在多個併發調用者的情況下,最後的調用者將首先返回,反之亦然。在很多情況下,您需要使用某種類型的鍵保存來電者信息,以便在獲得異步事件時查找。
這也可以在gen_fsm進程中完成;函數調用和返回值是相似的。
謝謝!這正是我需要的。我完全忘了{noreply,...}「迴歸」。 – peitur
要小心這樣做,因爲'gen_server:call'具有5秒的內置超時,之後會自動生成一個錯誤。超時的長度可以用第三個參數設置,無論是millisecs還是'infinity'。 – rvirding
是的,我在之前的應用程序中遇到過這個問題。現在我通常會設置無窮大或者傳遞一個超時值(用於回調)。這確實使事情有點「凌亂」,儘管:( – peitur