4

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

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

4

2 回答 2

4

好的。现在,为了学习的目的,让我们做一个非常基本的例子。其他人会谈论OTP Supervisors, Process dictionaries等,但我想保持轻松学习目的。举个例子,生成器可以知道它创建了多少进程,它们的Pids,知道它们何时死亡等

-模块(发电机)。
-编译(export_all)。
-定义(错误(X),错误记录器:错误报告(X))。
开始()-> 寄存器(发电机,产卵(乐趣()->发电机()结束)), 好的。
生成器()-> 进程缓冲区 = [], process_flag(trap_exit,true), 循环(进程缓冲区)。
创建(模块,功能,参数)-> 发电机 !{create_new_proc,{Module,Function,Args}}, 好的。
send_to_kids(消息)-> 发电机 !{tell_kids,消息}, 好的。
循环(缓冲区)-> 收到 {create_new_proc,{M,F,A}} -> Pid = spawn(M,F,A), 链接(PID), 循环([Pid|缓冲区]); {tell_kids,消息} -> [ 孩子 !{广播,留言} || 孩子 <- 缓冲区], 循环(缓冲区); {'EXIT',SomePid,Reason} -> ?ERROR(["孩子崩溃了",{pid,SomePid},{reason,Reason}]), 循环(列表:删除(SomePid,缓冲区)); _ -> 循环(缓冲区) 结尾。
child_loop()-> 收到 {广播,消息} -> io:format("\n\tChild: ~p got: ~p~n",[self(),Message]), child_loop(); _ -> child_loop() 结尾。
在 shell 中测试
E:\应用程序>erl
Eshell V5.9(使用 ^G 中止)
1> c(生成器)。
{好的,发电机}
2> 发生器:开始()。
好的
3> 生成器:创建(生成器,child_loop,[])。
好的
4> [生成器:创建(生成器,child_loop,[])|| _ <- 列表:seq(1,5)],好的。
好的
5> generator:send_to_kids("Erlang 很好!").
        孩子:<0.45.0> 得到:“二郎好!”
        孩子:<0.44.0> 得到:“二郎好!”
        孩子:<0.43.0> 得到:“二郎好!”
        孩子:<0.42.0> 得到:“二郎好!”
        孩子:<0.41.0> 得到:“二郎好!”
        孩子:<0.39.0> 得到:“二郎好!”
好的
6> 发生器:send_to_kids("1+1 = 2")。
        孩子:<0.45.0> 得到:“1+1 = 2”
        孩子:<0.44.0> 得到:“1+1 = 2”
        孩子:<0.43.0> 得到:“1+1 = 2”
        孩子:<0.42.0> 得到:“1+1 = 2”
        孩子:<0.41.0> 得到:“1+1 = 2”
        孩子:<0.39.0> 得到:“1+1 = 2”
好的
7>
注册为generator已启动的进程可能会被告知启动任意数量的子进程。子进程通常是从{M, F, A}发送到generator. 生成器循环保留创建的进程的跟踪记录。然后可以告诉它向所有进程广播消息。

但是,在实践/生产中,您可能不会这样做,因为generator随着列表的增长,循环可能会消耗大量内存,Buffer因为这是我们保留所有Pids进程的地方。您也可以使用ETS Tables, or Mnesiaetc 但我没有在示例中使用它们,因为它们看起来更高级一些。查看此问题及其答案以了解更多信息。

于 2012-12-05T07:51:00.803 回答
1

您可以查看:http ://www.erlang.org/doc/design_principles/des_princ.html在 os Erlang 中“生成器”是“主管”

于 2012-12-05T05:58:37.653 回答