设为首页 加入收藏

TOP

erlang trap_exit标记(一)
2017-10-09 14:05:14 】 浏览:5827
Tags:erlang trap_exit 标记

本篇博文分析设置了 trap_exit 标记为 true 的 gen_server 进程会如何处理收到的退出信号。

设置了 trap_exittrue 的进程,在收到 非kill 的退出信号时候,会把该信号转换为普通的消息,而不会退出;
通过 gen_server:handle_msg/5gen_server:handle_msg/6 函数可知,若进程自身发生错误的时候,即使设置了 trap_exit 为 true,进程最终也会调用 ?MODULE:terminate/2 进行退出。 

用简单的例子验证:

 1 -module(test_gen_server).
 2 
 3 -behavior(gen_server).
 4 
 5 %% apis
 6 -export([
 7     start/0,
 8     start_link/0
 9 ]).
10 
11 %% callbacks
12 -export([
13     init/1,
14     handle_call/3,
15     handle_cast/2,
16     handle_info/2,
17     terminate/2,
18     code_change/3
19 ]).
20 
21 %% 字符串宏
22 -define(str_concat(Format, Args), lists:flatten(io_lib:format(Format, Args))).
23 
24 %% 日志宏
25 -define(err(Format, Args), error_logger:error_report(?str_concat("Module: ~p, Line:~p~n" ++ Format, [?MODULE, ?LINE | Args]))).
26 -define(info(Format, Args), io:format(?str_concat(Format ++ " in Module: ~p at Line: ~p~n", Args ++ [?MODULE, ?LINE]), [])).
27 
28 %% 进程状态结构定义
29 -record(state, {}).
30 
31 %% Apis -------------------------------
32 start() ->
33     gen_server:start({local, ?MODULE}, ?MODULE, [], []).
34 
35 start_link() ->
36     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
37 
38 %% Callbacks --------------------------
39 init([]) ->
40     ?info("gen_server: ~p init !", [?MODULE]),
41     erlang:process_flag(trap_exit, true),
42     {ok, #state{}}.
43 
44 handle_call(_Msg, _From, State) ->
45     {reply, reply, State}.
46 
47 handle_cast(_Msg, State) ->
48     {noreply, State}.
49 
50 handle_info(Msg, State) ->
51     ?info("recv info msg: ~p !", [Msg]),
52     {noreply, State}.
53 
54 terminate(normal, _State) ->
55     ?info("gen_server: ~p stopped, reason: normal", [?MODULE]);
56 terminate(Reason, _State) ->
57     ?err("gen_server: ~p stopped, reason: ~p", [?MODULE, Reason]).
58 
59 code_change(_OldVsn, State, _Extra) ->
60     {ok, State}.
61 
62 %% Privates ---------------------------

 

编译这个 test_gen_server 模块,然后在erlang shell里面做如下测试:

E:\Worksapce\erlang_test>erl -pa ebin/
Eshell V7.1  (abort with ^G)
1> {ok, Pid} = test_gen_server:start().
gen_server: test_gen_server init ! in Module: test_gen_server at Line: 34
{ok,<0.33.0>}
2> erlang:exit(Pid, stop).
recv info msg: {'EXIT',<0.31.0>,stop} ! in Module: test_gen_server at Line: 45
true
3> erlang:exit(Pid, shutdown).
recv info msg: {'EXIT',<0.31.0>,shutdown} ! in Module: test_gen_server at Line: 45
true
4> erlang:exit(Pid, any).
recv info msg: {'EXIT',<0.31.0>,any} ! in Module: test_gen_server at Line: 45
true
5> erlang:exit(Pid, kill).
true

从上面测试结果来看,在收到 kill 退出信号之前,test_gen_server 都把退出信号转换为普通消息,并通过51行的info宏打印出来了;
但在收到 kill 退出信号时,并没有 ?MODULE:terminate/2 函数的打印,因为 test_gen_server 收到 kill 信号后无条件的马上终止了,而没有执行 ?MODULE:terminate/2 函数。

把设置 trap_exit 进程标记的 41 行注释掉,编译并重新加载 test_gen_server 模块再进行测试:

1> {ok, Pid} = test_gen_server:start().
gen_server: test_gen_server init ! in Module: test_gen_server at Line: 35
{ok,<0.33.0>}
2> erlang:exit(Pid, normal).
true
3> erlang:is_process_alive(Pid).
true
4> erlang:exit(Pid, any).
true
5> erlang:is_process_alive(Pid).
false
6> {ok, Pid2} =
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇有关一些搜刮来的Erlang资源 下一篇Appmon启动错误

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目