[Erlang 0076] Erlang Shell一個怪問題

來源:互聯網
上載者:User

 

   最近一直在忙,偶爾有點時間在讀書,補充一下能量;最近在學習 程式設計語言-實踐之路 非常感慨,之前誤打誤撞的一點所得原來有一個更系統,完整的知識體系;於是沉下心來,慢慢吸收.像北上廣這樣的城市快速的代謝著我們的精力和知識,不容懈怠,不過倒也不必急躁,如果心浮氣躁,效果必然大打折扣;抽時間整理一下最近的筆記,先從一個怪異的問題開始吧!

 

  在Erlang shell中我常常建立一個無限等待接收訊息的進程來做一些測試,代碼:spawn(fun() -> receive after infinity-> io:format("DONE!") end end).問題複現步驟:1.在Erlang Shell中啟動這個進程之後 2.向該進程發送訊息 3.由於沒有訊息提取的邏輯,該進程收到的訊息就會積壓在訊息佇列裡面,可以通過erlang:process_info查看;首先使用Shell進程來試一下,可以看到結果是和我們的預期一致的:

 

 

23> [self()!abc || _<-lists:seq(1,20)].[abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc]24> erlang:process_info(self()).      [{current_function,{erl_eval,do_apply,6}},{initial_call,{erlang,apply,2}},{status,running},{message_queue_len,20},{messages,[abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,abc,            abc,abc,abc,abc,abc,abc,abc,abc]},{links,[<0.26.0>]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.25.0>},{total_heap_size,5168},{heap_size,2584},{stack_size,24},{reductions,68319},{garbage_collection,[{min_bin_vheap_size,46368},                      {min_heap_size,233},                      {fullsweep_after,65535},                      {minor_gcs,16}]},{suspending,[]}] 
   下面我們使用spawn(fun)的方式試一下,看下面的結果,在發送了兩條訊息之後查看進程狀態,發現訊息佇列是空的!!!

 

Erlang R15B (erts-5.9) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]Eshell V5.9  (abort with ^G)1> P=spawn(fun() -> receive after infinity-> io:format("dONE!") end end).<0.34.0>2> P!abc.abc3> P!abcd.abcd4> erlang:process_info(P).[{current_function,{erl_eval,receive_clauses,8}},{initial_call,{erlang,apply,2}},{status,waiting},{message_queue_len,0},{messages,[]},{links,[]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.25.0>},{total_heap_size,233},{heap_size,233},{stack_size,10},{reductions,26},{garbage_collection,[{min_bin_vheap_size,46368},                      {min_heap_size,233},                      {fullsweep_after,65535},                      {minor_gcs,0}]},{suspending,[]}]

 

  難道是這樣的寫法在Erlang Shell中有問題?我就把這段代碼放在一個測試模組中試一下:
-module(t).-compile(export_all).a() ->     receive          {Data}-> io:format("reveive Data :~p~n ",[Data]),         a()    after infinity ->          io:format("Done!")    end.b() -> spawn(fun() -> receive after infinity-> io:format("dONE!") end end). 
  運行上面的代碼t:b(),發送訊息,然後查看進程狀態,$$$$~~~~~~,看到了沒有,這種寫法訊息佇列裡面是可以看到積壓的訊息的!! 那麼之前的寫法,接收到的訊息在哪裡呢?

 

5> t:b().<0.39.0>6> v(5)!abc.abc7> v(5)!abcd.abcd8> erlang:process_info(v(5)).[{current_function,{t,'-b/0-fun-0-',0}},{initial_call,{erlang,apply,2}},{status,waiting},{message_queue_len,2},{messages,[abc,abcd]},{links,[]},{dictionary,[]},{trap_exit,false},{error_handler,error_handler},{priority,normal},{group_leader,<0.25.0>},{total_heap_size,233},{heap_size,233},{stack_size,0},{reductions,2},{garbage_collection,[{min_bin_vheap_size,46368},                      {min_heap_size,233},                      {fullsweep_after,65535},                      {minor_gcs,0}]},{suspending,[]}]

 

   訊息有可能在哪裡呢?還有一個辦法,我們把stacktrace輸出一下,從下面的結果中我們可以看到一點端倪:進程P的堆棧資訊中y(2) [abcd,abc]就是之前我們香它發送的訊息;查看一下t:b()進程,並沒有看到類似的資訊;通過對比,突破點應該在這裡,但是苦於沒有找到process_dsiplay輸出資訊的詳細說明,難以繼續了,記錄於此,日後繼續

9> bt(P).Program counter: 0x00007f738b7d76c0 (erl_eval:receive_clauses/8 + 168)CP: 0x0000000000000000 (invalid)arity = 00x00007f738d11c2d0 Return addr 0x000000000084e1b8 (<terminate process normally>)y(0)     []y(1)     valuey(2)     [abcd,abc]y(3)     {value,#Fun<shell.7.20862592>}y(4)     {eval,#Fun<shell.24.20862592>}y(5)     []y(6)     {[{call,1,{remote,1,{atom,1,io},{atom,1,format}},[{string,1,"dONE!"}]}],[]}y(7)     []y(8)     infinityok10> bt(v(5)).Program counter: 0x00007f73852f7ec0 (t:'-b/0-fun-0-'/0 + 8)CP: 0x000000000084e1b8 (<terminate process normally>)arity = 0ok11> 

 

最後貼張圖,今年銀河印象的作品 車手

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.