您的位置:首页 > 职场人生

Erlang入门:进程实例操作与练习3(选修)

2015-01-11 15:51 447 查看
%% @author Rolong

-module(process3).
-compile(export_all).

-define(I(F), io:format(F++"~n", [])).
-define(I(F, A), io:format(F++"~n", A)).

%%'TEST
%% vim cmd: '<,'>s/\([PE]\)3/\14/g
test1() ->
P1 = process3:start(fun1),
E1 = process3:on_exit(P1),
utils:sleep(100),
exit(P1, kill),
utils:sleep(100),
chk_alive("[kill P1] P1", P1),
chk_alive("[kill P1] E1", E1),

P2 = process3:start(fun1),
E2 = process3:on_exit(P2),
utils:sleep(100),
exit(P2, normal),
utils:sleep(100),
chk_alive("[normal P2] P2", P2),
chk_alive("[normal P2] E2", E2),

P3 = process3:start(fun1),
E3 = process3:on_exit(P3),
utils:sleep(100),
exit(E3, kill),
utils:sleep(100),
chk_alive("[kill E3] P3", P3),
chk_alive("[kill E3] E3", E3),

P4 = process3:start(fun1),
E4 = process3:on_exit(P4),
utils:sleep(100),
exit(E4, normal),
utils:sleep(100),
chk_alive("[normal E4] P4", P4),
chk_alive("[normal E4] E4", E4),
ok.

test2() ->
P1 = process3:start(fun1),
E1 = process3:on_exit(P1),
utils:sleep(100),
exit(P1, stop),
utils:sleep(100),
chk_alive("[stop P1] P1", P1),
chk_alive("[stop P1] E1", E1),

P2 = process3:start(fun1),
E2 = process3:on_exit(P2),
utils:sleep(100),
exit(P2, normal),
utils:sleep(100),
chk_alive("[normal P2] P2", P2),
chk_alive("[normal P2] E2", E2),

P3 = process3:start(fun1),
E3 = process3:on_exit(P3),
utils:sleep(100),
exit(E3, stop),
utils:sleep(100),
chk_alive("[stop E3] P3", P3),
chk_alive("[stop E3] E3", E3),

P4 = process3:start(fun1),
E4 = process3:on_exit(P4),
utils:sleep(100),
exit(E4, normal),
utils:sleep(100),
chk_alive("[normal E4] P4", P4),
chk_alive("[normal E4] E4", E4),
ok.
%%.

on_exit(Pid) ->
spawn(fun() ->
process_flag(trap_exit, true),
link(Pid),
on_exit_fun()
end).

on_exit_fun() ->
receive
{'EXIT', Pid, Reason} ->
?I("Exit signal from ~p, Reason:~p", [Pid, Reason]),
on_exit_fun();
Msg ->
?I("on_exit_fun receive: ~p", [Msg]),
on_exit_fun()
end.

start(Fun) ->
spawn(?MODULE,Fun,[]).

fun1() ->
receive
stop -> ok;
Msg ->
?I("fun1 receive: ~p", [Msg]),
fun1()
end.

%% ========= Internal Functions =========

chk_alive(Name, Pid) ->
case erlang:is_process_alive(Pid) of
true ->
io:format("~s(~p) is alive.~n", [Name, Pid]);
false ->
io:format("~s(~p) is NOT alive.~n", [Name, Pid])
end.

%% exit函数 文档
%%
%% exit(Pid, Reason) -> true
%%     Pid = pid()
%%     Reason = term()
%% Sends an exit signal with exit reason Reason to the process Pid.
%%
%% The following behavior apply if Reason is any term except normal or kill:
%%
%% If Pid is not trapping exits, Pid itself will exit with exit reason Reason. If Pid is trapping exits, the exit signal is transformed into a message {'EXIT', From, Reason} and delivered to the message queue of Pid. From is the pid of the process which sent the exit signal. See also process_flag/2.
%%
%% If Reason is the atom normal, Pid will not exit. If it is trapping exits, the exit signal is transformed into a message {'EXIT', From, normal} and delivered to its message queue.
%%
%% If Reason is the atom kill, that is if exit(Pid, kill) is called, an untrappable exit signal is sent to Pid which will unconditionally exit with exit reason killed.
%% vim: set filetype=erlang foldmarker=%%',%%. foldmethod=marker:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息