检查邮箱是否为空?在二郎

时间:2011-10-21 15:31:23

标签: erlang

我需要进行检查,返回true或false,具体取决于当前进程在erlang的邮箱中是否有任何消息。

3 个答案:

答案 0 :(得分:13)

您可以使用process_info/2 BIF访问进程信息,包括消息队列。所以

process_info(self(), message_queue_len) => {message_queue_len,Length}

process_info(self(), messages) => {messages,MessageList}

如果队列中有很多消息,则第二个是低效的,因为为每个调用创建了列表(当然不是消息)。关于流程,您可以找到很多有趣的事情。您可以获取信息的流程没有限制,您可以为任何流程执行此操作。

答案 1 :(得分:4)

您应该可以0使用receive超时。在下面的示例中,它将尝试从队列中获取消息,如果其中没有消息,则它将返回原子false

1> receive _ -> true  
1> after 0 ->
1> false
1> end.
empty

警告 会消息。

另一种方法是使用erlang:process_info但这应该仅用于调试。

6> {message_queue_len, QueueLen} = erlang:process_info(self(), message_queue_len).
{message_queue_len,0}
7> QueueLen.
0

现在:

16> HasMessages = fun(Pid) ->                                           
16>     element(2, erlang:process_info(Pid, message_queue_len)) > 0     
16> end.
#Fun<erl_eval.6.80247286>
17> HasMessages(self()).                                                                      
false
18> self() ! test.
test
19> HasMessages(self()).
true

答案 2 :(得分:1)

在内部,有一种方法可以测试进程邮箱中是否有消息。

但要注意!我不认为Erlang是这样用的:

{module, hasMsg}.
{exports, [{module_info,0},{module_info,1},{hasMsg,0},{peekMsg,1},{lastMsg,1}]}.
{attributes, []}.
{labels, 17}.

{function, hasMsg, 0, 2}.
    {label,1}.
        {func_info,{atom,hasMsg},{atom,hasMsg},0}.
    {label,2}.
        {loop_rec,{f,4},{x,0}}.
        {move,{atom,true},{x,0}}.
        return.
    {label,3}.
        {loop_rec_end,{f,2}}.
    {label,4}.
        timeout.
        {move,{atom,false},{x,0}}.
        return.

{function, peekMsg, 1, 6}.
    {label,5}.
        {func_info,{atom,hasMsg},{atom,peekMsg},1}.
    {label,6}.
        {loop_rec,{f,8},{x,0}}.
        return.
    {label,7}.
        {loop_rec_end,{f,6}}.
    {label,8}.
        timeout.
        return.

{function, lastMsg, 1, 10}.
    {label,9}.
        {func_info,{atom,hasMsg},{atom,lastMsg},1}.
    {label,10}.
        {loop_rec,{f,12},{x,0}}.
        {test,is_eq_exact,{f,11},[]}.
    {label,11}.
        {loop_rec_end,{f,10}}.
    {label,12}.
        timeout.
        return.

{function, module_info, 0, 14}.
    {label,13}.
        {func_info,{atom,hasMsg},{atom,module_info},0}.
    {label,14}.
        {move,{atom,hasMsg},{x,0}}.
        {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.

{function, module_info, 1, 16}.
    {label,15}.
        {func_info,{atom,hasMsg},{atom,module_info},1}.
    {label,16}.
        {move,{x,0},{x,1}}.
        {move,{atom,hasMsg},{x,0}}.
        {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.

编译:{{1​​}}。

模块erlc +from_asm hasMsg.S包含:

  • hasMsg返回一个布尔值,邮箱中是否有邮件。
  • hasMsg/0返回最旧的邮件而不删除它。如果邮箱为空,则返回其参数。
  • peekMsg/1返回最新消息而不删除它。如果邮箱为空,则返回其参数。