2017-08-19 60 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