2011-10-21 41 views
5

Tôi cần phải thực hiện một kiểm tra, trả về true hoặc false, tùy thuộc vào quá trình hiện tại có bất kỳ thông báo nào trong hộp thư của nó trong erlang hay không.Kiểm tra xem hộp thư có trống không? trong erlang

+0

Vấn đề lớn hơn là tìm thư cuối cùng trong hộp thư của quy trình. – damned

Trả lời

4

Bạn sẽ có thể sử dụng 0 cho thời gian chờ receive. Trong ví dụ dưới đây, nó sẽ cố gắng để có được một tin nhắn ra khỏi hàng đợi, nếu không có gì trong đó, nó sẽ trả về nguyên tử false.

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

Cảnh báo này sẽ tiêu thụ thư.

Một cách khác là sử dụng erlang:process_info nhưng điều này được cho là chỉ để gỡ lỗi.

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

Tổng cộng bây giờ:

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

Xin lỗi, nhưng câu trả lời của bạn là sai. Mã của bạn lãng phí một thông điệp và do đó làm gián đoạn tính chính xác của bất kỳ tính toán nào. –

+0

Có hai câu trả lời, vui lòng đọc kỹ. –

+0

Ngoài ra, có một cảnh báo rằng nó sẽ tiêu thụ tin nhắn. –

1

Bên trong có những phương tiện để kiểm tra nếu có một tin nhắn trong hộp thư quá trình.

Nhưng hãy cẩn thận! Tôi không nghĩ rằng Erlang có nghĩa là được sử dụng như thế:

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

Biên dịch: erlc +from_asm hasMsg.S.

Module hasMsg chứa:

  • hasMsg/0 trả về một boolean dù có những tin nhắn trong hộp thư.
  • peekMsg/1 trả về thư cũ nhất mà không xóa thư. Trả về đối số của nó, nếu hộp thư trống.
  • lastMsg/1 trả về thư mới nhất mà không xóa thư. Trả về đối số của nó, nếu hộp thư trống.
+2

Tôi sẽ không làm theo cách này trừ khi bạn có khuynh hướng tự sát và yêu thích lắp ráp hack. Những hướng dẫn này không được xác định và không có sự đảm bảo nào sẽ được giữ nguyên. Tôi đưa ra một cách hơi sạch hơn bên dưới. – rvirding

+0

@rvirding, tôi sẽ không bao giờ sử dụng mã như vậy. Tôi chỉ muốn xem nếu nó có thể. Hacking đến giới hạn. ;) Tôi muốn nói thuật toán của một người hoàn toàn bị hỏng, nếu người dùng phải xem tin nhắn mới nhất hoặc cũ nhất trong hộp thư… – kay

9

Bạn có thể sử dụng process_info/2 BIF để truy cập thông tin quy trình bao gồm hàng đợi tin nhắn. Vì vậy,

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

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

Điều thứ hai là không hiệu quả nếu có nhiều thông điệp trong hàng đợi như danh sách được tạo ra cho mỗi cuộc gọi (mặc dù không phải là thông điệp của khóa học). Có nhiều điều thú vị bạn có thể tìm hiểu về một quy trình. Không có giới hạn về quy trình nào bạn có thể nhận được thông tin, bạn có thể làm điều đó cho bất kỳ quá trình nào.

Các vấn đề liên quan