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

教父的告白
一切都是紙老虎
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 暗夜教父 閱讀(340) 評論(0)  編輯 收藏 引用 所屬分類: erlang

<2009年9月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用鏈接

留言簿(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>
            国产日韩欧美高清免费| 亚洲一区二区三区四区视频| 亚洲素人在线| 日韩写真视频在线观看| 日韩亚洲一区二区| 中文日韩在线| 亚洲欧美日韩国产中文| 欧美一区二区三区日韩视频| 亚洲婷婷国产精品电影人久久| 亚洲黄色免费电影| 国产伦精品一区二区三区免费迷| 欧美乱妇高清无乱码| 国产精品久久9| 国产欧美高清| 亚洲国产成人久久| 在线视频欧美一区| 性刺激综合网| 久久综合网络一区二区| 欧美激情亚洲激情| 亚洲无线一线二线三线区别av| 午夜免费电影一区在线观看| 久久er精品视频| 美女免费视频一区| 欧美三级中文字幕在线观看| 国产综合精品| 亚洲精品日本| 久久国产精彩视频| 亚洲欧洲另类国产综合| 午夜一区二区三区不卡视频| 欧美96在线丨欧| 国产精品视频免费观看www| 在线视频观看日韩| 亚洲综合国产精品| 欧美91视频| 亚洲一区二区在线看| 免费在线看一区| 国产精品私房写真福利视频| 亚洲精品国产精品国自产观看| 欧美一区二区精品| 亚洲激情一区二区三区| 久久精品99国产精品| 欧美另类久久久品| 亚洲国产精品第一区二区| 欧美在线国产精品| 99国内精品久久| 欧美岛国在线观看| 国产最新精品精品你懂的| 亚洲主播在线| 亚洲精品免费电影| 欧美黄色精品| 亚洲人永久免费| 鲁大师成人一区二区三区| 羞羞视频在线观看欧美| 欧美体内谢she精2性欧美| 999在线观看精品免费不卡网站| 美女图片一区二区| 久久99伊人| 国产欧美三级| 欧美一级视频| 亚洲淫片在线视频| 国产精品嫩草影院av蜜臀| 亚洲一区二区三区高清不卡| 亚洲清纯自拍| 欧美极品色图| 99亚洲一区二区| 亚洲国产经典视频| 国产在线观看精品一区二区三区 | 亚洲国产精品久久久| 亚洲伊人久久综合| 欧美激情在线有限公司| 久久久久网址| 黄色在线一区| 欧美暴力喷水在线| 你懂的亚洲视频| 一个色综合av| 亚洲天堂免费在线观看视频| 国产精品免费aⅴ片在线观看| 欧美亚洲午夜视频在线观看| 小嫩嫩精品导航| 狠狠色2019综合网| 欧美成黄导航| 欧美日韩精品欧美日韩精品| 亚洲一区在线视频| 欧美一区二区视频观看视频| 精品福利电影| 亚洲黑丝在线| 欧美日韩国产一区二区三区| 亚洲一区日本| 欧美影视一区| 亚洲精品视频在线播放| 一本色道久久综合亚洲精品不| 国产精品免费一区二区三区在线观看 | 亚洲国产精品123| 亚洲国产精品尤物yw在线观看| 欧美久久电影| 欧美一区二区三区视频在线 | 亚洲女女做受ⅹxx高潮| 欧美一区二区三区在线观看| 亚洲国产美国国产综合一区二区| 亚洲精品一区二区三区樱花 | 久久精品亚洲国产奇米99| 亚洲三级影院| 亚洲自拍高清| 亚洲人永久免费| 欧美在线free| 一区二区电影免费观看| 久久精品官网| 亚洲免费影视| 免费久久精品视频| 久久精品日韩欧美| 欧美日韩一区二区三区免费看| 久久一区二区三区av| 欧美系列精品| 最新日韩在线视频| 曰韩精品一区二区| 亚洲欧美一区二区激情| 99精品国产一区二区青青牛奶| 久久久777| 久久久精彩视频| 欧美性理论片在线观看片免费| 免费短视频成人日韩| 国产婷婷一区二区| 欧美一级一区| 亚洲一区二区三区国产| 亚洲国产精彩中文乱码av在线播放 | 一区国产精品| 午夜精品久久久99热福利| 亚洲一级黄色| 欧美激情亚洲国产| 亚洲国产成人av| 激情久久综合| 校园激情久久| 欧美一区二区网站| 国产精品久久久久久久久动漫 | 久久久另类综合| 久久精品日产第一区二区| 国产精品免费福利| 亚洲在线视频观看| 欧美尤物一区| 国产视频久久| 久久成人综合网| 久久一二三四| 亚洲国产片色| 欧美电影免费观看| 亚洲精品1区2区| 99精品欧美一区二区三区综合在线 | 99精品免费网| 亚洲午夜精品久久久久久浪潮| 欧美日韩国产色站一区二区三区| 亚洲精品国产精品久久清纯直播 | 欧美网站大全在线观看| 中文亚洲字幕| 久久成人av少妇免费| 国内伊人久久久久久网站视频| 久久精品中文字幕免费mv| 久久在线播放| 亚洲精品国产精品国产自| 欧美日本在线| 亚洲免费一级电影| 乱码第一页成人| 亚洲毛片在线观看.| 欧美午夜宅男影院| 久久久久国产一区二区三区| 欧美本精品男人aⅴ天堂| 亚洲精品影视| 国产精品入口麻豆原神| 欧美一级淫片aaaaaaa视频| 美女爽到呻吟久久久久| 99精品国产热久久91蜜凸| 国产精品无码专区在线观看| 久久免费午夜影院| 一本色道久久| 巨乳诱惑日韩免费av| 日韩午夜三级在线| 国产一区二区激情| 欧美精品一区二区三区一线天视频| 亚洲无线视频| 欧美大片在线影院| 亚洲免费一级电影| 亚洲国产精品一区二区第一页| 欧美午夜精品一区| 久久午夜精品| 亚洲永久字幕| 亚洲国产精品电影在线观看| 亚欧成人精品| 日韩手机在线导航| 久久综合狠狠综合久久综青草| 亚洲国产美女| 国产精品网站一区| 欧美激情一区二区| 香港久久久电影| 亚洲精品综合| 狂野欧美激情性xxxx欧美| 先锋资源久久| 一区二区三区四区国产| 亚洲高清不卡av| 国产一区999| 国产精品高潮久久| 欧美日韩国产影院| 欧美成年人网|