2011-10-21 22 views

cevap

4

receive zaman aşımı için 0 kullanabilmeniz gerekir. Aşağıdaki örnekte, false numaralı atomu döndürecek hiçbir şey yoksa, kuyruktan bir mesaj almayı deneyecektir.

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

bu olacak bir ileti tüketmek uyarı olun.

Başka bir yöntem de erlang:process_info kullanmak olabilir, ancak bu yalnızca hata ayıklama için sözde. Tamamen hemen

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

Üzgünüz, ama cevabınız yanlış. Kodunuz bir mesajı boşa harcar ve dolayısıyla herhangi bir bilginin doğruluğunu bozar. –

+0

İki cevap var, lütfen iyice okuyun. –

+0

Ayrıca, iletiyi tüketeceği konusunda bir uyarı var. –

1

Dahili işlem posta kutusunda bir mesaj olup olmadığını test etmek araçlar vardır.

Ama dikkat! Ben Erlang böyle kullanılacak anlamına sanmıyorum:

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

Derleme: erlc +from_asm hasMsg.S.

modülü hasMsg içerir:

  • hasMsg/0 posta kutusu içinde mesaj olup bir boolean döndürür.
  • peekMsg/1 en eski iletiyi kaldırmadan döndürür. Posta kutusu boşsa, argümanını döndürür. En yeni iletiyi kaldırmadan
  • lastMsg/1 döndürür. Posta kutusu boşsa, argümanını döndürür.
+2

İntihara meyilli ve aşk derleyicisini korsanlığa uğratmadıkça bu şekilde yapmayacağım. Bu talimatlar tanımlanmamıştır ve kalacağı garantiler yoktur. Aşağıda biraz daha temiz bir şekilde vereceğim. – rvirding

+0

@rvirding, Ben asla böyle bir kod kullanmazdım. Sadece mümkün olup olmadığını görmek istedim. Limite kesmek. ;) Birinin, posta kutusundaki en yeni veya en eski iletiye göz atması gerekiyorsa, algoritmasının tamamen kırıldığını söyleyebilirim… – kay

9

İleti kuyruğu dahil olmak üzere işlem bilgilerine erişmek için process_info/2 BIF kullanabilirsiniz. Yani

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

ve

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

ikincisi liste her arama için oluşturulan olarak kuyrukta birçok mesaj olup olmadığını verimsizdir (gerçi değil elbette mesajlar). Bir süreç hakkında öğrenebileceğiniz birçok ilginç şey var. Hangi işlem hakkında bilgi alabileceğiniz konusunda herhangi bir kısıtlama yoktur, herhangi bir işlem için bunu yapabilirsiniz.

İlgili konular