青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

教父的告白
一切都是紙老虎
posts - 82,  comments - 7,  trackbacks - 0
  任何一門語言都有自己的錯誤處理機制,Erlang也不例外,語法錯誤編譯器可以幫你指出,而邏輯錯誤和運行時錯誤就只有靠程序員利用Erlang提供的機制來妥善處理,放置程序的崩潰。
    Erlang的機制有:
1)監控某個表達式的執行
2)監控其他進程的行為
3)捕捉未定義函數執行錯誤等

一、catch和throw語句
    調用某個會產生錯誤的表達式會導致調用進程的非正常退出,比如錯誤的模式匹配(2=3),這種情況下可以用catch語句:
                                      catch expression
    試看一個例子,一個函數foo:

java 代碼
 
  1. foo(1) ->  
  2. hello;  
  3. foo(2) ->  
  4. throw({myerror, abc});  
  5. foo(3) ->  
  6. tuple_to_list(a);  
  7. foo(4) ->  
  8. exit({myExit, 222}).  

當沒有使用catch的時候,假設有一個標識符為Pid的進程調用函數foo(在一個模塊中),那么:
foo(1) - 返回hello
foo(2) - 語句throw({myerror, abc})執行,因為我們沒有在一個catch中調用foo(2),因此進程Pid將因為錯誤而終止。

foo(3) - tuple_to_list將一個元組轉化為列表,因為a不是元組,因此進程Pid同樣因為錯誤而終止

foo(4) - 因為沒有使用catch,因此foo(4)調用了exit函數將使進程Pid終止,{myExit, 222} 參數用于說明退出的原因。

foo(5) - 進程Pid將因為foo(5)的調用而終止,因為沒有和foo(5)匹配的函數foo/1。

    讓我們看看用catch之后是什么樣:
java 代碼
 
  1. demo(X) ->  
  2. case catch foo(X) of  
  3.   {myerror, Args} ->  
  4.        {user_error, Args};  
  5.   {'EXIT', What} ->  
  6.        {caught_error, What};  
  7.   Other ->  
  8.        Other  
  9. end.  

再看看結果,
demo(1) - 沒有錯誤發生,因此catch語句將返回表達式結果hello
demo(2) - foo(2)拋出錯誤{myerror, abc},被catch返回,因此將返回{user_error,abc}

demo(3) - foo(3)執行失敗,因為參數錯誤,因此catch返回{'EXIT',badarg'},最后返回{caught_error,badarg}

demo(4) - 返回{caught_error,{myexit,222}}
demo(5) - 返回{caught_error,function_clause}

    使用catch和throw可以將可能產生錯誤的代碼包裝起來,throw可以用于尾遞歸的退出等等。Erlang是和scheme一樣進行尾遞歸優化的,它們都沒有顯式的迭代結構(比如for循環)

二、進程的終止
    在進程中調用exit的BIFs就可以顯式地終止進程,exit(normal)表示正常終止,exit(Reason)通過Reason給出非正常終止的原因。進程的終止也完全有可能是因為運行時錯誤引起的。

三、連接的進程
    進程之間的連接是雙向的,也就是說進程A打開一個連接到B,也意味著有一個從B到A的連接。當進程終止的時候,有一個EXIT信號將發給所有與它連接的進程。信號的格式如下:
               {'EXIT', Exiting_Process_Id, Reason}
Exiting_Process_Id 是指終止的進程標記符
Reason 是進程終止的原因。如果Reason是normal,接受這個信號的進程的默認行為是忽略這個信號。默認對Exit信號的處理可以被重寫,以允許進程對Exit信號的接受做出不同的反應。
1.連接進程:
通過link(Pid),就可以在調用進程與進程Pid之間建立連接
2.取消連接
反之通過unlink(Pid)取消連接。
3.創立進程并連接:
通過spawn_link(Module, Function, ArgumentList)創建進程并連接,該方法返回新創建的進程Pid

    通過進程的相互連接,許多的進程可以組織成一個網狀結構,EXIT信號(非normal)從某個進程發出(該進程終止),所有與它相連的進程以及與這些進 程相連的其他進程,都將收到這個信號并終止,除非它們實現了自定義的EXIT信號處理方法。一個進程鏈狀結構的例子:
java 代碼
 
  1. -module(normal).  
  2. -export([start/1, p1/1, test/1]).  
  3. start(N) ->  
  4. register(start, spawn_link(normal, p1, [N - 1])).  
  5.  p1(0) ->  
  6.    top1();  
  7.  p1(N) ->  
  8.    top(spawn_link(normal, p1, [N - 1]),N).  
  9. top(Next, N) ->  
  10. receive  
  11. X ->  
  12. Next ! X,  
  13. io:format("Process ~w received ~w~n", [N,X]),  
  14. top(Next,N)  
  15. end.  
  16. top1() ->  
  17. receive  
  18. stop ->  
  19. io:format("Last process now exiting ~n", []),  
  20. exit(finished);  
  21. X ->  
  22. io:format("Last process received ~w~n", [X]),  
  23. top1()  
  24. end.  
  25. test(Mess) ->  
  26. start ! Mess.  

執行:
java 代碼
 
  1. > normal:start(3).  
  2. true  
  3. > normal:test(123).  
  4. Process 2 received 123  
  5. Process 1 received 123  
  6. Last process received 123  
  7.   
  8. > normal:test(stop).  
  9. Process 2 received stop  
  10. Process 1 received stop  
  11. Last process now exiting  
  12. stop  

四、運行時失敗
    一個運行時錯誤將導致進程的非正常終止,伴隨著非正常終止EXIT信號將發出給所有連接的進程,EXIT信號中有Reason并且Reason中包含一個atom類型用于說明錯誤的原因,常見的原因如下:

badmatch - 匹配失敗,比如一個進程進行1=3的匹配,這個進程將終止,并發出{'EXIT', From, badmatch}信號給連接的進程

badarg  - 顧名思義,參數錯誤,比如atom_to_list(123),數字不是atom,因此將發出{'EXIT', From, badarg}信號給連接進程

case_clause - 缺少分支匹配,比如
   
java 代碼
 
  1. M = 3,  
  2. case M of  
  3.   1 ->  
  4.     yes;  
  5.   2 ->  
  6.     no  
  7. end.  

沒有分支3,因此將發出{'EXIT', From, case_clause}給連接進程

if_clause - 同理,if語句缺少匹配分支

function_clause - 缺少匹配的函數,比如:
java 代碼
 
  1. foo(1) ->  
  2.   yes;  
  3. foo(2) ->  
  4.   no.  

如果我們調用foo(3),因為沒有匹配的函數,將發出{'EXIT', From, function_clause} 給連接的進程。

undef - 進程執行一個不存在的函數

badarith - 非法的算術運算,比如1+foo。

timeout_value - 非法的超時時間設置,必須是整數或者infinity

nocatch - 使用了throw,沒有相應的catch去通訊。

五、修改默認的信號接收action
   當進程接收到EXIT信號,你可以通過process_flag/2方法來修改默認的接收行為。執行process_flag(trap_exit, true)設置捕獲EXIT信號為真來改變默認行為,也就是將EXIT信號作為一般的進程間通信的信號進行接受并處理;process_flag (trap_exit,false)將重新開啟默認行為。
   例子:
java 代碼
 
  1. -module(link_demo).  
  2. -export([start/0, demo/0, demonstrate_normal/0, demonstrate_exit/1,  
  3. demonstrate_error/0, demonstrate_message/1]).  
  4. start() ->  
  5.   register(demo, spawn(link_demo, demo, [])).  
  6. demo() ->  
  7.   process_flag(trap_exit, true),  
  8. demo1().  
  9.   demo1() ->  
  10.   receive  
  11.     {'EXIT', From, normal} ->  
  12.       io:format("Demo process received normal exit from ~w~n",[From]),  
  13.      demo1();  
  14.     {'EXIT', From, Reason} ->  
  15.       io:format("Demo process received exit signal ~w from ~w~n",[Reason, From]),  
  16.      demo1();  
  17.     finished_demo ->  
  18.       io:format("Demo finished ~n", []);  
  19.     Other ->  
  20.       io:format("Demo process message ~w~n", [Other]),  
  21.      demo1()  
  22.   end.  
  23. demonstrate_normal() ->  
  24.   link(whereis(demo)).  
  25. demonstrate_exit(What) ->  
  26.   link(whereis(demo)),  
  27.   exit(What).  
  28. demonstrate_message(What) ->  
  29.   demo ! What.  
  30. demonstrate_error() ->  
  31.   link(whereis(demo)),  
  32.   1 = 2.  
  33.    

    創建的進程執行demo方法,demo方法中設置了trap_exit為true,因此,在receive中可以像對待一般的信息一樣處理EXIT信號,這個程序是很簡單了,測試看看:
java 代碼
 
  1. > link_demo:start().  
  2. true  
  3. > link_demo:demonstrate_normal().  
  4. true  
  5. Demo process received normal exit from <0.13.1>  
  6. > link_demo:demonstrate_exit(hello).  
  7. Demo process received exit signal hello from <0.14.1>  
  8. ** exited: hello **  
  9.   
  10. > link_demo:demonstrate_exit(normal).  
  11. Demo process received normal exit from <0.13.1>  
  12. ** exited: normal **  
  13.   
  14. > link_demo:demonstrate_error().  
  15. !!! Error in process <0.17.1> in function  
  16. !!! link_demo:demonstrate_error()  
  17. !!! reason badmatch  
  18. ** exited: badmatch **  
  19. Demo process received exit signal badmatch from <0.17.1>  

六、未定義函數和未注冊名字
1.當調用一個未定義的函數時,Mod:Func(Arg0,...,ArgN),這個調用將被轉為:
error_handler:undefined_function(Mod, Func, [Arg0,...,ArgN])
其中的error_handler模塊是系統自帶的錯誤處理模塊

2.當給一個未注冊的進程名發送消息時,調用將被轉為:
error_handler:unregistered_name(Name,Pid,Message)

3.如果不使用系統自帶的error_handler,可以通過process_flag(error_handler, MyMod) 設置自己的錯誤處理模塊。

七、Catch Vs. Trapping Exits
這兩者的區別在于應用場景不同,Trapping Exits應用于當接收到其他進程發送的EXIT信號時,而catch僅用于表達式的執行。

第8章介紹了如何利用錯誤處理機制去構造一個健壯的系統,用了幾個例子,我將8.2節的例子完整寫了下,并添加客戶端進程用于測試:
java 代碼
 
  1. -module(allocator).  
  2. -export([start/1,server/2,allocate/0,free/1,start_client/0,loop/0]).  
  3. start(Resources) ->  
  4.    Pid = spawn(allocator, server, [Resources,[]]),  
  5. register(resource_alloc, Pid).  
  6. %函數接口  
  7. allocate() ->  
  8.    request(alloc).  
  9. free(Resource) ->  
  10.   request({free,Resource}).  
  11. request(Request) ->  
  12.   resource_alloc ! {self(),Request},  
  13.   receive  
  14.     {resource_alloc, error} ->  
  15.       exit(bad_allocation); % exit added here  
  16.     {resource_alloc, Reply} ->  
  17.       Reply  
  18.  end.  
  19. % The server.  
  20. server(Free, Allocated) ->  
  21.  process_flag(trap_exit, true),  
  22.  receive  
  23.    {From,alloc} ->  
  24.          allocate(Free, Allocated, From);  
  25.    {From,{free,R}} ->  
  26.         free(Free, Allocated, From, R);  
  27.    {'EXIT', From, _ } ->  
  28.        check(Free, Allocated, From)  
  29.  end.  
  30. allocate([R|Free], Allocated, From) ->  
  31.    link(From),  
  32.    io:format("連接客戶端進程~w~n",[From]),  
  33.    From ! {resource_alloc,{yes,R}},  
  34.    server(Free, [{R,From}|Allocated]);  
  35. allocate([], Allocated, From) ->  
  36.    From ! {resource_alloc,no},  
  37.    server([], Allocated).  
  38. free(Free, Allocated, From, R) ->  
  39.   case lists:member({R,From}, Allocated) of  
  40.    true ->  
  41.               From ! {resource_alloc,ok},  
  42.               Allocated1 = lists:delete({R, From}, Allocated),  
  43.               case lists:keysearch(From,2,Allocated1) of  
  44.                      false->  
  45.                             unlink(From),  
  46.                         io:format("從進程~w斷開~n",[From]);  
  47.                      _->  
  48.                             true  
  49.               end,  
  50.              server([R|Free],Allocated1);  
  51.    false ->  
  52.            From ! {resource_alloc,error},  
  53.          server(Free, Allocated)  
  54.  end.  
  55.   
  56. check(Free, Allocated, From) ->  
  57.    case lists:keysearch(From, 2, Allocated) of  
  58.          false ->  
  59.            server(Free, Allocated);  
  60.         {value, {R, From}} ->  
  61.            check([R|Free],  
  62.            lists:delete({R, From}, Allocated), From)  
  63. end.  
  64. start_client()->  
  65.     Pid2=spawn(allocator,loop,[]),  
  66.     register(client, Pid2).  
  67. loop()->  
  68.     receive  
  69.         allocate->  
  70.             allocate(),  
  71.             loop();  
  72.         {free,Resource}->  
  73.             free(Resource),  
  74.             loop();  
  75.         stop->  
  76.             true;  
  77.         _->  
  78.             loop()  
  79.     end.  
  80.       

回家了,有空再詳細說明下這個例子吧。執行:
java 代碼
 
  1. 1> c(allocator).  
  2. {ok,allocator}  
  3. 2> allocator:start([1,2,3,4,5,6]).  
  4. true  
  5. 3> allocator:start_client().  
  6. true  
  7. 4> client!allocate  
  8. .  
  9. allocate連接客戶端進程<0.37.0>  
  10.   
  11. 5> client!allocate.  
  12. allocate連接客戶端進程<0.37.0>  
  13.   
  14. 6> client!allocate.  
  15. allocate連接客戶端進程<0.37.0>  
  16.   
  17. 7> allocator:allocate().  
  18. 連接客戶端進程<0.28.0>  
  19. {yes,4}  
  20. 8> client!{free,1}.  
  21. {free,1}  
  22. 9> client!{free,2}.  
  23. {free,2}  
  24. 10> client!allocate.  
  25. allocate連接客戶端進程<0.37.0>  
  26.   
  27. 11> client!allocate.  
  28. allocate連接客戶端進程<0.37.0>  
  29.   
  30. 12> client!stop.  
  31. stop  
  32. 13> allocator:allocate().  
  33. 連接客戶端進程<0.28.0>  
  34. {yes,3}  
  35. 14> allocator:allocate().  
  36. 連接客戶端進程<0.28.0>  
  37. {yes,2}  
  38. 15> allocator:allocate().  
  39. 連接客戶端進程<0.28.0>  
  40. {yes,1}  
  41. 16>  

posted on 2009-09-11 10:13 暗夜教父 閱讀(335) 評論(0)  編輯 收藏 引用 所屬分類: erlang

<2009年10月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用鏈接

留言簿(2)

隨筆分類

隨筆檔案

文章分類

文章檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产亚洲精品一区二555| 日韩亚洲国产欧美| 欧美中文在线观看国产| 99这里只有精品| 日韩视频在线一区二区| 亚洲午夜精品久久久久久app| 亚洲综合大片69999| 亚洲国产精品一区二区www在线| 久久亚洲一区| 欧美不卡高清| 一区二区久久久久久| 欧美日韩视频在线第一区| 亚洲欧洲精品一区二区三区不卡| 在线观看日韩国产| 午夜精品久久久久久久久久久久久| 99视频有精品| 欧美午夜大胆人体| 久久精品国产99| 亚洲人成网站影音先锋播放| 91久久久久久久久| 欧美日韩一区二区在线观看视频| 久久精品国产精品亚洲综合| 久久久亚洲午夜电影| 欧美精品导航| 国产欧美一区视频| 亚洲国产成人精品视频| 亚洲尤物精选| 久久影院亚洲| 亚洲欧美激情一区| 欧美三日本三级少妇三2023| 国产自产v一区二区三区c| 欧美中文字幕精品| 国产精品婷婷午夜在线观看| 欧美日韩一区二区视频在线| 久久精品一区二区三区不卡| 亚洲欧洲在线观看| 久久性天堂网| 亚洲女性喷水在线观看一区| 久久亚洲一区二区| 欧美专区一区二区三区| 亚洲男人影院| 亚洲自拍偷拍色片视频| 欧美中文字幕不卡| 欧美黄色免费网站| 欧美一二三区精品| 欧美在线亚洲综合一区| 91久久夜色精品国产九色| 亚洲国产黄色| 亚洲人成啪啪网站| 女人色偷偷aa久久天堂| 亚洲欧美日韩国产综合在线 | 亚洲午夜激情| 久久精品国产91精品亚洲| 一区二区三区欧美成人| 亚洲丰满少妇videoshd| 9国产精品视频| 久久久久综合网| 香蕉成人啪国产精品视频综合网| 国产精品日韩电影| 老牛国产精品一区的观看方式| 久久久蜜臀国产一区二区| 亚洲精品欧美在线| 伊人成人在线视频| 欧美大片免费观看| 国产美女精品一区二区三区| 欧美 日韩 国产精品免费观看| 欧美巨乳在线观看| 亚洲第一区在线| 国产综合视频| 亚洲欧美另类在线| 亚洲天堂av在线免费观看| 久久亚洲精选| 永久91嫩草亚洲精品人人| 亚洲高清视频在线| 永久久久久久| 开心色5月久久精品| 欧美在线日韩在线| 欧美日韩在线免费视频| 亚洲成色777777在线观看影院| 伊人久久噜噜噜躁狠狠躁| 99成人精品| 久久国内精品视频| 欧美一区二区日韩| 国产欧美精品在线播放| 欧美在线观看一二区| 欧美一区二区三区在线视频| 国产精品videossex久久发布| 亚洲欧洲在线免费| 亚洲午夜一区二区| 国产精品男gay被猛男狂揉视频| 亚洲午夜在线观看视频在线| 午夜在线a亚洲v天堂网2018| 国产日韩欧美在线观看| 久久免费视频观看| 亚洲国产成人精品女人久久久 | 国产精品欧美久久| 一本大道av伊人久久综合| 欧美专区在线播放| 亚洲国产成人高清精品| 欧美国产欧美综合| 久久一综合视频| 亚洲视频在线二区| 欧美中文字幕| 99这里只有精品| 久久九九免费| 一区二区三区高清在线| 欧美一区二区三区免费观看| 亚洲欧洲日产国码二区| 亚洲视频一区在线观看| 影音先锋亚洲视频| 亚洲无玛一区| 日韩一级视频免费观看在线| 亚洲中午字幕| 亚洲人成欧美中文字幕| 欧美在线|欧美| 亚洲一区二区三区四区视频| 久久综合国产精品| 久久久xxx| 国产精品免费一区豆花| 99国产精品99久久久久久粉嫩| 亚洲国产成人精品久久久国产成人一区 | 欧美激情第二页| 国产精品视频免费一区| 亚洲福利视频专区| 好看的av在线不卡观看| 午夜伦理片一区| 午夜精品福利在线| 欧美亚洲成人免费| 夜夜爽夜夜爽精品视频| 一区二区三区不卡视频在线观看| 久久精品一区二区三区四区 | 欧美国产日本| 黄色成人在线观看| 欧美一区二区三区四区视频| 亚洲免费在线精品一区| 欧美日本一区二区三区| 免费日韩av电影| 亚洲成人在线免费| 久久久亚洲精品一区二区三区 | 亚洲香蕉在线观看| 亚洲欧美激情视频| 国产精品久久久久久久9999| 亚洲精品欧洲| 宅男噜噜噜66一区二区| 欧美片在线播放| 一区二区三区四区五区在线| 亚洲在线一区二区三区| 国产精品美女久久久久久2018 | 麻豆freexxxx性91精品| 亚洲国产导航| 亚洲手机在线| 欧美一级淫片aaaaaaa视频| 国产美女精品视频| 欧美一区二区三区免费视频 | 男人天堂欧美日韩| 亚洲成人资源网| 欧美aaa级| 亚洲精品在线观| 午夜视频在线观看一区二区三区 | 亚洲一区二区黄| 国产欧美日本| 老司机一区二区三区| 亚洲大胆av| 亚洲图片自拍偷拍| 国产日韩av一区二区| 美女日韩在线中文字幕| 亚洲日本成人| 欧美一区国产一区| 在线观看欧美精品| 欧美国产成人在线| 在线视频亚洲欧美| 美女网站久久| 亚洲综合第一页| 亚洲国产成人久久综合| 国产精品美女久久| 久久综合中文| 亚洲女人小视频在线观看| 欧美阿v一级看视频| 亚洲无限乱码一二三四麻| 国产视频久久久久久久| 欧美激情欧美激情在线五月| 欧美一级网站| 亚洲精品视频免费观看| 久久精品人人做人人综合| 亚洲毛片在线看| 韩国精品久久久999| 欧美日韩在线电影| 久久人体大胆视频| 欧美一二三区在线观看| 亚洲日本欧美天堂| 欧美阿v一级看视频| 久久精品欧美| 欧美诱惑福利视频| 亚洲男人的天堂在线观看| 日韩网站在线观看| 亚洲经典视频在线观看| 激情久久五月天| 国产一区视频在线看| 国产精品视频一区二区三区 | 国产精品激情av在线播放|