- 特殊进程
- 例子
- 例子
特殊进程
本节将描述如何编写符合OTP设计原理而又不使用标准行为的进程。这样的一种进程要:
- 以一种可以让进程放入监督树的方式启动,
- 支持 sys 的 调试功能 ,以及
- 注意 系统消息 。系统消息是用于监督树中的带有特殊含义的消息。典型的系统消息有跟踪输出的请求、挂起和恢复进程执行的请求(用于发布处理中)。使用标准行为实现的进程会自动处理这些消息。
例子
来自 概述 一章中的简单服务器,如果使用 sys 和 proc_lib 实现并放入一个监督树,则为:
- -module(ch4).
- -export([start_link/0]).
- -export([alloc/0, free/1]).
- -export([init/1]).
- -export([system_continue/3, system_terminate/4,
- write_debug/3]).
- start_link() ->
- proc_lib:start_link(ch4, init, [self()]).
- alloc() ->
- ch4 ! {self(), alloc},
- receive
- {ch4, Res} ->
- Res
- end.
- free(Ch) ->
- ch4 ! {free, Ch},
- ok.
- init(Parent) ->
- register(ch4, self()),
- Chs = channels(),
- Deb = sys:debug_options([]),
- proc_lib:init_ack(Parent, {ok, self()}),
- loop(Chs, Parent, Deb).
- loop(Chs, Parent, Deb) ->
- receive
- {From, alloc} ->
- Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
- ch4, {in, alloc, From}),
- {Ch, Chs2} = alloc(Chs),
- From ! {ch4, Ch},
- Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
- ch4, {out, {ch4, Ch}, From}),
- loop(Chs2, Parent, Deb3);
- {free, Ch} ->
- Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
- ch4, {in, {free, Ch}}),
- Chs2 = free(Ch, Chs),
- loop(Chs2, Parent, Deb2);
- {system, From, Request} ->
- sys:handle_system_msg(Request, From, Parent,
- ch4, Deb, Chs)
- end.
- system_continue(Parent, Deb, Chs) ->
- loop(Chs, Parent, Deb).
- system_terminate(Reason, Parent, Deb, Chs) ->
- exit(Reason).
- write_debug(Dev, Event, Name) ->
- io:format(Dev, "~p event = ~p~n", [Name, Event]).
以及如何在 ch4 中使用 sys 中的简易调试函数:
- % erl
- Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
- Eshell V5.2.3.6 (abort with ^G)
- 1> ch4:start_link().
- {ok,<0.30.0>}
- 2> sys:statistics(ch4, true).
- ok
- 3> sys:trace(ch4, true).
- ok
- 4> ch4:alloc().
- ch4 event = {in,alloc,<0.25.0>}
- ch4 event = {out,{ch4,ch1},<0.25.0>}
- ch1
- 5> ch4:free(ch1).
- ch4 event = {in,{free,ch1}}
- ok
- 6> sys:statistics(ch4, get).
- {ok,[{start_time,{{2003,6,13},{9,47,5}}},
- {current_time,{{2003,6,13},{9,47,56}}},
- {reductions,109},
- {messages_in,2},
- {messages_out,1}]}
- 7> sys:statistics(ch4, false).
- ok
- 8> sys:trace(ch4, false).
- ok
- 9> sys:get_status(ch4).
- {status,<0.30.0>,
- {module,ch4},
- [[{'$ancestors',[<0.25.0>]},{'$initial_call',{ch4,init,[<0.25.0>]}}],
- running,<0.25.0>,[],
- [ch1,ch2,ch3]]}