Erlang中的一个常见模式是维护状态的递归循环:
loop(State) ->
receive
Msg ->
NewState = whatever(Msg),
loop(NewState)
end.
Run Code Online (Sandbox Code Playgroud)
有没有办法用bif或跟踪查询正在运行的进程的状态?由于崩溃消息说"......状态是......"并显示崩溃进程的状态,我认为这很容易,但我很失望,因为我无法找到这样做的bif.
那么,我认为使用dbg模块的跟踪就可以了.不幸的是,我相信因为这些循环是尾调用优化的,所以dbg只捕获对该函数的第一次调用.
有解决方案吗
gle*_*ber 27
如果您的进程使用OTP,那就足够了sys:get_status(Pid).
您提到的错误消息由SASL显示.SASL是OTP中的错误报告守护程序.
您在示例代码中引用的状态只是尾递归函数的参数.除了跟踪BIF之外,没有办法使用任何东西来提取它.我想这不是生产代码中的正确解决方案,因为跟踪仅用于调试目的.
正确的,经过行业测试的解决方案将在您的项目中广泛使用OTP.然后,您可以充分利用SASL错误报告,rb模块来收集这些报告,sys- 检查正在运行的OTP兼容流程的状态,proc_lib- 使短期流程符合OTP标准等.
看起来你是在无中生有地制造问题。erlang:process_info/1 提供了足够的信息用于调试目的。如果您确实需要循环函数参数,为什么不将其返回给调用者以响应您自己定义的特殊消息之一?
更新:只是为了澄清术语。在语言级别上最接近“进程状态”的是进程字典,强烈建议不要使用它。可以通过 erlang:process_info/1 或 erlang:process/2 查询。您实际需要的是跟踪进程的本地函数调用及其参数:
-module(ping).
-export([start/0, send/1, loop/1]).
start() ->
spawn(?MODULE, loop, [0]).
send(Pid) ->
Pid ! {self(), ping},
receive
pong ->
pong
end.
loop(S) ->
receive
{Pid, ping} ->
Pid ! pong,
loop(S + 1)
end.
Run Code Online (Sandbox Code Playgroud)
安慰:
Erlang (BEAM) emulator version 5.6.5 [source] [smp:2] [async-threads:0] [kernel-poll:false]
Eshell V5.6.5 (abort with ^G)
1> l(ping).
{module,ping}
2> erlang:trace(all, true, [call]).
23
3> erlang:trace_pattern({ping, '_', '_'}, true, [local]).
5
4> Pid = ping:start().
<0.36.0>
5> ping:send(Pid).
pong
6> flush().
Shell got {trace,<0.36.0>,call,{ping,loop,[0]}}
Shell got {trace,<0.36.0>,call,{ping,loop,[1]}}
ok
7>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9999 次 |
| 最近记录: |