如何告诉进程创建另一个进程并跟踪它

时间:2012-12-04 22:14:00

标签: erlang distributed

如何告诉特定进程(让我们称之为生成器)在Erlang中创建一个新进程?

另外,如何跟踪生成器创建的所有进程?

2 个答案:

答案 0 :(得分:4)

好。现在,为了学习的目的,让我们做一个非常基本的例子。其他人会谈到OTP Supervisors, Process dictionaries e.t.c.但我想让它容易学习。举个例子,生成器可以知道它创建了多少个进程,它们的Pids知道它们何时死掉e.t.c.

-module(generator).
-compile(export_all).
-define(ERROR(X),error_logger:error_report(X)).
start()-> register(generator,spawn(fun() -> generator() end)), ok.
generator()-> ProcessBuffer = [], process_flag(trap_exit,true), loop(ProcessBuffer).
create(Module,Function,Args)-> generator ! {create_new_proc,{Module,Function,Args}}, ok.
send_to_kids(Message)-> generator ! {tell_kids,Message}, ok.
loop(Buffer)-> receive {create_new_proc,{M,F,A}} -> Pid = spawn(M,F,A), link(Pid), loop([Pid|Buffer]); {tell_kids,Message} -> [ Kid ! {broadcast,Message} || Kid <- Buffer], loop(Buffer); {'EXIT',SomePid,Reason} -> ?ERROR(["Child has crashed",{pid,SomePid},{reason,Reason}]), loop(lists:delete(SomePid,Buffer)); _ -> loop(Buffer) end.
child_loop()-> receive {broadcast,Message} -> io:format("\n\tChild: ~p got: ~p~n",[self(),Message]), child_loop(); _ -> child_loop() end.
在shell
E:\Applications>erl
Eshell V5.9  (abort with ^G)
1> c(generator).
{ok,generator}
2> generator:start().
ok
3> generator:create(generator,child_loop,[]).
ok
4> [generator:create(generator,child_loop,[]) || _ <- lists:seq(1,5)],ok.
ok
5> generator:send_to_kids("Erlang is good !").
        Child: <0.45.0> got: "Erlang is good !"
        Child: <0.44.0> got: "Erlang is good !"
        Child: <0.43.0> got: "Erlang is good !"
        Child: <0.42.0> got: "Erlang is good !"
        Child: <0.41.0> got: "Erlang is good !"
        Child: <0.39.0> got: "Erlang is good !"
ok
6> generator:send_to_kids("1+1 = 2").
        Child: <0.45.0> got: "1+1 = 2"
        Child: <0.44.0> got: "1+1 = 2"
        Child: <0.43.0> got: "1+1 = 2"
        Child: <0.42.0> got: "1+1 = 2"
        Child: <0.41.0> got: "1+1 = 2"
        Child: <0.39.0> got: "1+1 = 2"
ok
7>
中进行测试 注册为generator的进程已启动,可能会被告知启动任意数量的子进程。子进程通常是根据发送到{M, F, A}的{​​{1}}组合创建的。生成器循环保持创建的进程的跟踪记录。然后可以告诉它向所有进程广播消息。

但是,在实践/生产中,您可能不会这样做,因为generator循环可能会消耗大量内存,因为列表generator增长,因为我们保留了Buffer的所有Pids流程。您也可以使用ETS TablesMnesia e.t.c,但我没有在示例中使用它们,因为它们看起来会更先进一些。请查看此question及其answer以了解更多信息。

答案 1 :(得分:1)

您可以查看:http://www.erlang.org/doc/design_principles/des_princ.html在术语中,Erlang“Generator”是“主管”