erlang中的link/0函數能夠使2個進程互相聯繫在一塊兒,其中一個進程結束後,另一個會收到這個進程的結束緣由,咱們能夠根據這個緣由信息來進行一些處理。shell
但要注意的是,link/0函數若是使用不當的話,在一個進程結束後,另一個進程會緊跟着結束。下面直接上代碼。app
-module(linker). %% API -export([start/0, start/1, start2/1 ]). %% 這裏直接生成一個進程 start() -> spawn(fun() -> receive T -> %% 輸出任何收到的信息 io:format("T:~p, I~n", [T]) end end). %% 這裏對進程進行link()函數操做 start(Pid) -> spawn(fun() -> link(Pid), receive T -> io:format("T:~p~n", [T]) end end). %% 跟上面start/1函數同樣,多加了 %% process_flag(trap_exit, true) 操做 start2(Pid) -> spawn(fun() -> process_flag(trap_exit, true), link(Pid), receive T -> io:format("T:~p, I am ~p ~n", [T, self()]) end end).
上面創建了一個名爲linker.erl的文件,下面咱們在erlang shell裏面進行操做:async
$erlc linker.erl $erl Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:3:3] [async-threads:10] [hipe] [kernel-poll:false] Eshell V8.1 (abort with ^G) 1> Pid = linker:start(). <0.60.0> 2> Pid2 = linker:start(Pid). <0.62.0> 3> processes(). [<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>, <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>, <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>, <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>, <0.54.0>,<0.58.0>,<0.60.0>,<0.62.0>] 4> 4> exit(Pid, kill_process). true 5> processes(). [<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>, <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>, <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>, <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>, <0.54.0>,<0.58.0>] 6>
能夠看到上面生成了2個進程,進行link()函數後,2個進程連接在一塊兒。後來對Pid進行exit/2函數操做,2個進程沒有任何信息就同時結束了。 下面咱們繼續探討一下:ide
6> Pid3 = linker:start(). <0.67.0> 7> Pid4 = linker:start2(Pid3). <0.69.0> 8> processes(). [<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>, <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>, <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>, <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>, <0.54.0>,<0.58.0>,<0.67.0>,<0.69.0>] 9> exit(Pid3, kill_process). T:{'EXIT',<0.60.0>,kill_process}, I am <0.69.0> true 10>processes(). [<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>, <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>, <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>, <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>, <0.54.0>,<0.58.0>]
能夠看到多使用了process_flag(trap_exit, true)的函數後,不會跟着結束的進程無信息結束掉。 結論: 單獨使用link/0函數,2個連接的進程會同時結束;而多使用了process_flag(trap_exit, true)的進程則不會。 這個在<<Designing for Scalability with Erlang/OTP>>書中有提到:函數
Remember, though, that links are bidirectional, so if the server dies for some reason while client and server are linked, this will by default kill the client too, which you may not want to happen. If that’s the case, use a monitor instead of a link, as we explain in 「Monitors」. Exit signals can be trapped by calling the process_flag(trap_exit, true) function. This converts exit signals into messages of the form {'EXIT', Pid, Reason}, where Pid is the process identifier of the process that has died and Reason is the reason it has terminated. These messages are stored in the recipient’s mailbox and processed in the same way as all other messages. When a process is trapping exits, the exit signal is not propagated to any of the processes in its link set.Why does a process exit? This can happen for two reasons. If a process has no more code to execute, it terminates normally . The Reason propagated will be the atom normal. Abnormal termination is initiated in case of a runtime error, receiving an exit signal when not trapping exits, or by calling the exit BIFs. Called with a single argument, exit(Reason) will terminate the calling process with reason Reason, which will be propagated in the exit signal to any other processes to which the exiting one is linked. When the exit BIF is called with two arguments, exit(Pid, Reason), it sends an exit signal with reason Reason to the process Pid. This will have the same effect as if the calling process had terminated with reason Reason.this
此博文同時發表在簡書網頁atom