99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Erlang 錯誤處理

2022-07-07 15:43 更新

Erlang錯誤處理

在討論監(jiān)督與錯誤處理細節(jié)之前,讓我們先一起來看一下 Erlang 進程的終止過程,或者說 Erlang 的術語 exit。

進程執(zhí)行 exit(normal) 結(jié)束或者運行完所有的代碼而結(jié)束都被認為是進程的正常(normal)終止。

進程因為觸發(fā)運行時錯誤(例如,除零、錯誤匹配、調(diào)用不存在了函數(shù)等)而終止被稱之為異常終止。進程執(zhí)行 exit(Reason) (注意此處的 Reason 是除 normal 以外的值)終止也被稱之為異常終止。

一個 Erlang 進程可以與其它 Erlang 進程建立連接。如果一個進程調(diào)用 link(Other_Pid),那么它就在其自己與 Othre_Pid 進程之間創(chuàng)建了一個雙向連接。當一個進程結(jié)束時,它會發(fā)送信號至所有與之有連接的進程。

這個信號攜帶著進程的進程標識符以及進程結(jié)束的原因信息。

進程收到進程正常退出的信號時默認情況下是直接忽略它。

但是,如果進程收到的是異常終止的信號,則默認動作為:

  • 接收到異常終止信號的進程忽略消息隊列中的所有消息
  • 殺死自己
  • 將相同的錯誤消息傳遞給連接到它的所有進程。

所以,你可以使用連接的方式把同一事務的所有進程連接起來。如果其中一個進程異常終止,事務中所有進程都會被殺死。正是因為在實際生產(chǎn)過程中,常常有創(chuàng)建進程同時與之建立連接的需求,所以存在這樣一個內(nèi)置函數(shù) spawn_link,與 spawn 不同之處在于,它創(chuàng)建一個新進程同時在新進程與創(chuàng)建者之間建立連接。

下面給出了 ping pong 示例子另外一種實現(xiàn)方法,它通過連接終止 "pong" 進程:

-module(tut20).

-export([start/1,  ping/2, pong/0]).

ping(N, Pong_Pid) ->
    link(Pong_Pid),
    ping1(N, Pong_Pid).

ping1(0, _) ->
    exit(ping);

ping1(N, Pong_Pid) ->
    Pong_Pid ! {ping, self()},
    receive
        pong ->
            io:format("Ping received pong~n", [])
    end,
    ping1(N - 1, Pong_Pid).

pong() ->
    receive
        {ping, Ping_PID} ->
            io:format("Pong received ping~n", []),
            Ping_PID ! pong,
            pong()
    end.

start(Ping_Node) ->
    PongPID = spawn(tut20, pong, []),
    spawn(Ping_Node, tut20, ping, [3, PongPID]).
(s1@bill)3> tut20:start(s2@kosken).
Pong received ping
<3820.41.0>
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong

與前面的代碼一樣,ping pong 程序的兩個進程仍然都是在 start/1 函數(shù)中創(chuàng)建的,“ping”進程在單獨的結(jié)點上建立的。但是這里做了一些小的改動,用到了內(nèi)置函數(shù) link?!癙ing” 結(jié)束時調(diào)用 exit(ping) ,使得一個終止信號傳遞給 “pong” 進程,從而導致 “pong” 進程終止。

也可以修改進程收到異常終止信號時的默認行為,避免進程被殺死。即,把所有的信號都轉(zhuǎn)變?yōu)橐话愕南⑻砑拥叫盘柦邮者M程的消息隊列中,消息的格式為 {'EXIT',FromPID,Reason}。我們可以通過如下的代碼來設置:

process_flag(trap_exit, true)

還有其它可以用的進程標志,可參閱 erlang (3)。標準用戶程序一般不需要改變進程對于信號的默認處理行為,但是對于 OTP 中的管理程序這個接口還是很有必要的。下面修改了 ping pong 程序來打印輸出進程退出時的信息:

-module(tut21).

-export([start/1,  ping/2, pong/0]).

ping(N, Pong_Pid) ->
    link(Pong_Pid), 
    ping1(N, Pong_Pid).

ping1(0, _) ->
    exit(ping);

ping1(N, Pong_Pid) ->
    Pong_Pid ! {ping, self()},
    receive
        pong ->
            io:format("Ping received pong~n", [])
    end,
    ping1(N - 1, Pong_Pid).

pong() ->
    process_flag(trap_exit, true), 
    pong1().

pong1() ->
    receive
        {ping, Ping_PID} ->
            io:format("Pong received ping~n", []),
            Ping_PID ! pong,
            pong1();
        {'EXIT', From, Reason} ->
            io:format("pong exiting, got ~p~n", [{'EXIT', From, Reason}])
    end.

start(Ping_Node) ->
    PongPID = spawn(tut21, pong, []),
    spawn(Ping_Node, tut21, ping, [3, PongPID]).
(s1@bill)1> tut21:start(s2@gollum).
<3820.39.0>
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
pong exiting, got {'EXIT',<3820.39.0>,ping}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號