2017-08-19 101 views
1

我有一個坐在循環中並接收命令的進程。Erlang接收***警告***

receive 
    increase -> 
     ... 
    decrease -> 
     ... 
    after 5000 -> 
     ... 
end 

但是當我用數以千計的信息轟炸它時,它會發生故障並接收到這些警告。

警告消息:

***WARNING*** Unexp msg {<0.106.0>,rec_acked}, info {running, 
                [{'_UserConnections',20}], 
                {ieval,3994,34,log, 
                 clientLogging, 
                 [20], 
                 false}} 

反正是有來處理呢?它是否會導致任何問題?

謝謝你的回答!

+0

你可以嘗試創建一個減少的測試用例來觸發這個警告呢?這是我能找到這個確切警告的唯一實例:https://github.com/erlang/otp/blob/770454f0a32fbc0714c6762ed3e4d761b799814f/lib/debugger/src/dbg_icmd.erl#L225-L226。不知道爲什麼該進程正在接收'rec_acked'消息。 – Dogbert

+0

如果大約1000多個進程發送消息給1個PID(循環),就會發生這種情況。 – Mike5050

+3

必須有一些額外的條件觸發這一點。我從2000年產生的進程中發送2000條消息到一個進程,並且沒有警告消息(總共400萬條消息)。 Erlang VM當前使用500MB以上的RAM,因爲主進程沒有處理任何消息。 – Dogbert

回答

3

這個代碼僅僅是例子,實踐好,但不要在生產環境中運行。
您應始終收到來自流程郵箱的所有郵件,並在獲得後選擇您想要的內容。

handle_message() -> 
    receive 
     Msg -> 
      handle_message(Msg) 
    after 5000 -> 
      handle_timeout() 
    end. 

handle_message(increase) -> 
    ...; 
handle_message(decrease) -> 
    ...; 
handle_message(_) -> 
    %% Back to receiving loop 
    handle_message(). 

您應該防止填寫處理郵箱。
在生產就緒應用程序中,通常沒有人使用receive語句,它們通常使用一些標準代碼,這些代碼處理接收,超時,回覆,休眠等。我們將這些代碼稱爲行爲,例如OTP標準行爲之一是gen_server behavior
因爲OTP行爲是一般用途,如果你需要做一些特殊的工作非常有效率的代碼,你必須寫一個名爲Special process一些東西,應該處理自己的消息和Erlang系統消息。

+0

謝謝!我是在假設一個gen_server的準系統只是一個循環接收?另外,您如何防止填寫流程郵箱?正如你所猜測的那樣,這段代碼只會增加/減少連接的用戶。 – Mike5050

+0

另外,答案是,我仍然收到這些消息! – Mike5050

+0

你可以顯示代碼嗎?只需將消息發送到一個進程? – Pouriya