2011-10-21 18 views
5

Necesito hacer una comprobación, que devuelve verdadero o falso, dependiendo de si el proceso actual tiene algún mensaje en su buzón en erlang.Comprobar si el buzón está vacío en erlang

+0

El problema más amplio es encontrar el último mensaje en el buzón del proceso. – damned

Respuesta

4

Debería poder usar 0 para el tiempo de espera receive. En el siguiente ejemplo, intentará sacar un mensaje de la cola, si no hay ninguno, devolverá el átomo false.

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

se alerta a este se consumen un mensaje.

Otra forma sería usar erlang:process_info pero esto es supuestamente solo para la depuración.

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

En total ahora:

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 
+0

Lo siento, pero su respuesta es incorrecta. Su código desperdicia un mensaje y así interrumpe la corrección de cualquier cálculo. –

+0

Hay dos respuestas, por favor, lea a fondo. –

+0

Además, hay una advertencia de que consumirá el mensaje. –

1

Internamente hay medios para poner a prueba si hay un mensaje en el buzón proceso.

¡Pero cuidado! No creo Erlang está destinado a ser utilizado como esa:

{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}}. 

Compilar: erlc +from_asm hasMsg.S.

El módulo hasMsg contiene:

  • hasMsg/0 devuelve una regla booleana si hay mensajes en el buzón de correo.
  • peekMsg/1 devuelve el mensaje más antiguo sin quitarlo. Devuelve su argumento, si el buzón está vacío.
  • lastMsg/1 devuelve el mensaje más reciente sin eliminarlo. Devuelve su argumento, si el buzón está vacío.
+2

No lo haría de esta manera a menos que tengas tendencias suicidas y hagas hacking al ensamblador. Estas instrucciones no están definidas y no hay garantías de que permanecerán. Doy una manera ligeramente más clara a continuación. – rvirding

+0

@rvirding, nunca usaría ese código. Solo quería ver si era posible. Hackeando hasta el límite. ;) Yo diría que el algoritmo de uno está completamente roto, si uno tiene que mirar el mensaje más nuevo o más viejo en el buzón ... – kay

9

Puede usar el process_info/2 BIF para acceder a la información del proceso, incluida la lista de mensajes. Así

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

y

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

El segundo es ineficaz si hay muchos mensajes en la cola como se crea la lista para cada llamada (aunque no los mensajes, por supuesto). Hay muchas cosas interesantes que puedes descubrir sobre un proceso. No hay restricciones sobre qué proceso puede obtener información, puede hacerlo para cualquier proceso.

Cuestiones relacionadas