- 浏览: 32905 次
- 性别:
- 来自: 北京
最新评论
-
liumengfan:
{beam_dynamic_libraries, get_dy ...
system_info模块 -
liumengfan:
{environment, [split_env( ...
system_info模块 -
liumengfan:
其中{environment_erts, os_getenv ...
system_info模块 -
liumengfan:
centos再安装erlang之前,先安装如下软件:yum i ...
SystemTap and Erlang: a tutorial -
liumengfan:
判断是否是内部port的程序:#define is_inter ...
erlang判断内部pid的方法
引用Erlang如何查看gen_server系列的状态 (高级)
gen_server在erlang otp编程中的地位是无可撼动的,几乎都是gen_server或者gen_fsm的模型。那么程序运行起来的时候 我们如何查看gen_server的内部状态呢。有2种方法:
1. 自己写个类似于info这样的函数,来获取状态。
2. 利用系统现有的架构。sasl应用带了一个si的东西 全名是status inspector, 这个东西就是设计来帮用户解决这个问题的。
实验开始:
root@nd-desktop:~# cat abc.erl
-module(abc).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-export([format_status/2]).
-export([test/0]).
-record(state, {a, b}).
-define(SERVER, ?MODULE).
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
test()->
gen_server:call(?SERVER, {test, "param1"}).
init([]) ->
{ok, #state{a=hello, b=world}}.
handle_call({test, _} = Request, _From, State) ->
io:format("got msg ~p~n", [Request]),
{reply, ok, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
format_status(_Opt, [_PDict, #state{a=A,
b = B
}]) ->
[{data, [{"a===", A},
{"b===", B}]}].
root@nd-desktop:~# erl -boot start_sasl
Erlang R13B03 (erts-5.7.4) 1[/source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_safe_sup}
started: [{pid,<0.35.0>},
{name,alarm_handler},
{mfa,{alarm_handler,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_safe_sup}
started: [{pid,<0.36.0>},
{name,overload},
{mfa,{overload,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.34.0>},
{name,sasl_safe_sup},
{mfa,
{supervisor,start_link,
[{local,sasl_safe_sup},sasl,safe]}},
{restart_type,permanent},
{shutdown,infinity},
{child_type,supervisor}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.37.0>},
{name,release_handler},
{mfa,{release_handler,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
application: sasl
started_at: nonode@nohost
Eshell V5.7.4 (abort with ^G)
1> si:start(). %必须手动启动
=PROGRESS REPORT==== 29-Oct-2009::16:07:31 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.43.0>},
{name,si_server},
{mfa,{si_sasl_supp,start_link,[[]]}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,worker}]
{ok,<0.43.0>}
2> si:help().
Status Inspection tool - usage
==============================
For all these functions, Opt is an optional argument
which can be 'normal' or 'all'; default is 'normal'.
If 'all', all information will be printed.
A Pid can be: "<A.B.C>", {A, B, C}, B, a registered_name or an abbrev.
ANY PROCESS
si:pi([Opt,] Pid) - Formatted information about any process that
SI recognises.
si:pi([Opt,] A,B,C) - Same as si:pi({A, B, C}).
si:ppi(Pid) - Pretty formating of process_info.
Works for any process.
MISC
si:abbrevs() - Lists valid abbreviations.
si:start_log(Filename) - Logging to file.
si:stop_log()
si:start() - Starts Status Inspection (the si_server).
si:start([{start_log, FileName}])
si:stop() - Shut down SI.
ok
3> abc:start_link().
{ok,<0.46.0>}
4> abc:test().
got msg {test,"param1"}
ok
5> sys:log(abc,true). %打开gen_server的消息log功能
ok
6> abc:test(). %这个请求消息被记录
got msg {test,"param1"}
ok
7> si:pi(abc). %好戏开始
Status for generic server abc
===============================================================================
Pid <0.46.0>
Status running
Parent <0.41.0>
Logged events %这个是log到的消息
{10,
[{{out,ok,<0.41.0>,{state,hello,world}},
abc,
{gen_server,print_event}},
{{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>},{test,"param1"}}},
abc,
{gen_server,print_event}}]}
%这个是format_status的结果 如果没有format_status那么导出是 {a=hello, b=world}
a=== hello
b=== world
ok
8> si:ppi(abc).
Pretty Process Info
-------------------
[{registered_name,abc},
{current_function,{gen_server,loop,6}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[<0.41.0>]},
{dictionary,[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.25.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,9},
{reductions,117},
{garbage_collection,[{fullsweep_after,65535},{minor_gcs,0}]},
{suspending,[]}]
ok
9> sys:get_status(abc).
{status,<0.46.0>,
{module,gen_server},
[[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}],
running,<0.41.0>,
[{log,{10,
[{{out,ok,<0.41.0>,{state,hello,world}},
abc,
{gen_server,print_event}},
{{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>},
{test,"param1"}}},
abc,
{gen_server,print_event}}]}}],
[abc,{state,hello,world},abc,infinity]]}
结论:
这个是文档未公开的功能。上面演示了如何sys打开log, 如何察看gen_server的状态
引用
gen_server在erlang otp编程中的地位是无可撼动的,几乎都是gen_server或者gen_fsm的模型。那么程序运行起来的时候 我们如何查看gen_server的内部状态呢。有2种方法:
1. 自己写个类似于info这样的函数,来获取状态。
2. 利用系统现有的架构。sasl应用带了一个si的东西 全名是status inspector, 这个东西就是设计来帮用户解决这个问题的。
实验开始:
root@nd-desktop:~# cat abc.erl
-module(abc).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-export([format_status/2]).
-export([test/0]).
-record(state, {a, b}).
-define(SERVER, ?MODULE).
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
test()->
gen_server:call(?SERVER, {test, "param1"}).
init([]) ->
{ok, #state{a=hello, b=world}}.
handle_call({test, _} = Request, _From, State) ->
io:format("got msg ~p~n", [Request]),
{reply, ok, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
format_status(_Opt, [_PDict, #state{a=A,
b = B
}]) ->
[{data, [{"a===", A},
{"b===", B}]}].
root@nd-desktop:~# erl -boot start_sasl
Erlang R13B03 (erts-5.7.4) 1[/source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_safe_sup}
started: [{pid,<0.35.0>},
{name,alarm_handler},
{mfa,{alarm_handler,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_safe_sup}
started: [{pid,<0.36.0>},
{name,overload},
{mfa,{overload,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.34.0>},
{name,sasl_safe_sup},
{mfa,
{supervisor,start_link,
[{local,sasl_safe_sup},sasl,safe]}},
{restart_type,permanent},
{shutdown,infinity},
{child_type,supervisor}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.37.0>},
{name,release_handler},
{mfa,{release_handler,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
application: sasl
started_at: nonode@nohost
Eshell V5.7.4 (abort with ^G)
1> si:start(). %必须手动启动
=PROGRESS REPORT==== 29-Oct-2009::16:07:31 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.43.0>},
{name,si_server},
{mfa,{si_sasl_supp,start_link,[[]]}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,worker}]
{ok,<0.43.0>}
2> si:help().
Status Inspection tool - usage
==============================
For all these functions, Opt is an optional argument
which can be 'normal' or 'all'; default is 'normal'.
If 'all', all information will be printed.
A Pid can be: "<A.B.C>", {A, B, C}, B, a registered_name or an abbrev.
ANY PROCESS
si:pi([Opt,] Pid) - Formatted information about any process that
SI recognises.
si:pi([Opt,] A,B,C) - Same as si:pi({A, B, C}).
si:ppi(Pid) - Pretty formating of process_info.
Works for any process.
MISC
si:abbrevs() - Lists valid abbreviations.
si:start_log(Filename) - Logging to file.
si:stop_log()
si:start() - Starts Status Inspection (the si_server).
si:start([{start_log, FileName}])
si:stop() - Shut down SI.
ok
3> abc:start_link().
{ok,<0.46.0>}
4> abc:test().
got msg {test,"param1"}
ok
5> sys:log(abc,true). %打开gen_server的消息log功能
ok
6> abc:test(). %这个请求消息被记录
got msg {test,"param1"}
ok
7> si:pi(abc). %好戏开始
Status for generic server abc
===============================================================================
Pid <0.46.0>
Status running
Parent <0.41.0>
Logged events %这个是log到的消息
{10,
[{{out,ok,<0.41.0>,{state,hello,world}},
abc,
{gen_server,print_event}},
{{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>},{test,"param1"}}},
abc,
{gen_server,print_event}}]}
%这个是format_status的结果 如果没有format_status那么导出是 {a=hello, b=world}
a=== hello
b=== world
ok
8> si:ppi(abc).
Pretty Process Info
-------------------
[{registered_name,abc},
{current_function,{gen_server,loop,6}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[<0.41.0>]},
{dictionary,[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.25.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,9},
{reductions,117},
{garbage_collection,[{fullsweep_after,65535},{minor_gcs,0}]},
{suspending,[]}]
ok
9> sys:get_status(abc).
{status,<0.46.0>,
{module,gen_server},
[[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}],
running,<0.41.0>,
[{log,{10,
[{{out,ok,<0.41.0>,{state,hello,world}},
abc,
{gen_server,print_event}},
{{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>},
{test,"param1"}}},
abc,
{gen_server,print_event}}]}}],
[abc,{state,hello,world},abc,infinity]]}
结论:
这个是文档未公开的功能。上面演示了如何sys打开log, 如何察看gen_server的状态
发表评论
-
erlang host address
2014-03-07 13:40 767在rabbitMQ看到一段关于转换地址的代码: 留着以后用 ... -
record小记
2014-03-06 17:46 660今天阅读rabbitMQ代码,遇到一段代码很疑惑: try ... -
Distributed Semaphores with RabbitMQ
2014-03-04 21:54 1376翻译自(http://www.rabbitmq.com/blo ... -
system_info模块
2013-07-31 22:16 1124在看了Erlang新增全面的系统信息收集器-system_in ... -
erlang的gdb调试
2013-07-08 21:00 1620当我们完成erlang的正常配置和编译后,我们可以构建一个de ... -
SystemTap and Erlang: a tutorial
2013-07-06 19:16 1239参照该文章安装SystemTap and Erlang: a ... -
列表[A||boolen]
2013-07-06 16:14 814今天读到riak_sysmon时, ... -
erlang的erl_eval
2013-07-05 13:56 1204自己尝试使用erl_eval做一些联系,发掘改模块的功能: ... -
使用erlang实现动态替换字符串中的变量
2013-07-05 13:18 1627通过erlang,我们可以使用 {ok, Ts, _} = e ... -
使用erlang的动态执行编写DSL
2013-07-05 12:54 1389今天看到Erlang 动态执行和erlang动态解释, 实验的 ... -
通过port获取相应的节点名
2013-07-04 23:41 1024今天看了霸爷的节点间通讯的通道微调和谁引起busy_dist_ ... -
erlang的abstract_code代码
2013-07-04 21:04 701在看了霸爷的erlang的abstract code之后,自己 ... -
实验CPU密集型计算
2013-07-04 20:40 1271今天实验了一下霸爷博 ... -
erlang判断内部pid的方法
2013-07-04 13:48 1486在erl_term.h文件里: #define _TAG_ ... -
inet:setopts/2函数
2013-07-03 16:18 812下面引用霸爷的话,给自己做一个笔记 引用inet_drv内部每 ... -
erlang的内联编译
2013-07-02 23:42 1311今天再erlang inline 编译中读到erlang的函数 ... -
erlang:port_command函数
2013-07-02 22:10 3321今天读到褚霸博客里的g ... -
iolist类型
2013-07-02 21:47 843今天读到http://blog.yufeng.info的gen ... -
epmd的启动参数3
2013-07-01 21:28 1129和epmd相关的环境变量 ERL_EPMD_RELAXED_ ... -
epmd的启动参数2
2013-07-01 21:07 1099使用epmd的-port选项时,实验的例子是: [liuf ...
相关推荐
- 使用Erlang的`gen_server`行为模式编写服务进程,处理连接请求、数据收发等任务。 5. **文件结构**: - `tcp_client-master`可能包含源代码文件,如`.erl`文件,用于实现TCP客户端功能。 - 可能还有测试用例...
- **Gen_Server 行为**:文档中未给出具体细节,但通常涉及服务器进程的设计和实现。 - **Gen_Fsm 行为** - **有限状态机**:介绍了如何使用Gen_Fsm实现状态机逻辑。 - **示例**:提供了Gen_Fsm的具体用法示例。 ...
OTP(Open Telecom Platform)提供了诸如gen_server这样的行为模式,简化了分布式系统中的位置透明性和容错机制。 **Mnesia 分布数据库** Mnesia 是Erlang的分布式数据库系统,适合读多写少的场景。它提供了软实时...
- **2.3.1 有限状态机**:Erlang中的Gen_Fsm行为允许实现有限状态机。 - **2.3.2 实例**:提供了一个Gen_Fsm行为的实例。 - **2.3.3 启动一个Gen_Fsm**:如何启动一个有限状态机。 - **2.3.4 事情通知**:事件被...
- **有限状态机**: Gen_Fsm 用于创建有限状态机,可以用来模拟各种状态转换的过程。 - **实例**: 展示如何定义状态机和状态转换。 - **启动**: 使用 `gen_fsm:start/3` 函数启动一个Gen_Fsm实例。 - **事件通知*...
7. **OTP(Open Telecom Platform)**:Erlang OTP是一套标准库和设计原则,提供了如gen_server、gen_event等行为模式,帮助开发者遵循良好的软件工程实践。 在《Erlang编程指南》这本书中,作者Francesco Cesarini...
2. **使用高级抽象**:利用Erlang提供的高级抽象机制,比如`gen_server`和`gen_fsm`模块,这些模块可以帮助开发者更容易地构建复杂的分布式系统,同时避免底层细节带来的陷阱。 3. **错误处理与恢复**:设计应用...
2. OTP框架:理解其模块化设计、行为(gen_server, gen_event等)、分布式应用和系统监控。 3. RabbitMQ基本概念:掌握消息队列的工作原理、交换器(exchanges)、队列(queues)、绑定(bindings)以及消费者...
例如,Gen_Server和Gen_Fsm都是Erlang OTP提供的行为模式,它们定义了处理消息的基本结构,并要求开发者实现与具体逻辑相关的回调函数。 应用(Application)在Erlang/OTP中是一个封装了代码、模块、资源文件和配置...
查看Erlang内存使用情况 - **工具**: `observer`和`sys`提供了丰富的内存监控功能。 - **指标**: - **总内存**: 系统当前使用的总内存。 - **堆内存**: 进程堆内存使用量。 - **分配内存**: 当前已分配的内存...
- **Gen_Server、Gen_Fsm、Gen_Event**: OTP定义了多种通用的服务器行为,它们基于状态机和事件处理原则,允许开发者专注于业务逻辑的实现。 ### 总结 Erlang入门手册深入浅出地介绍了Erlang语言的基本概念,包括...
Erlang是一种高级编程语言,特别为并发、分布式计算和实时系统设计,广泛应用于电信、银行、互联网服务和嵌入式设备等领域。标题中的"erlang-23.3.4.11-1.el7.x86_64.zip"指示了这是一个Erlang的特定版本,即23.3....
- **并发控制**:Erlang提供了一些高级的并发控制原语,如`gen_server`行为,用于简化并发服务的实现。 - **超时处理**:在等待消息时,可以设置超时时间,如果超过这个时间仍未收到消息,则执行默认的动作。 - **...
3. **OTP(Open Telecom Platform)框架**:OTP是Erlang的标准库,提供了许多预定义的行为(Behaviours),如gen_server、gen_event和supervisor,它们是构建可靠系统的基石。理解这些行为及其使用方式是Erlang...
- `gen_server`目录下的代码展示了如何使用GenServer行为创建一个有状态的服务,处理客户端的请求和响应。 - `supervisor`和`gen_event`目录则分别演示了如何利用Supervisor监督树来管理和恢复子进程,以及如何使用...