Reputation: 1783
How can I tell a specific process (let's call it the generator) to create a new process in Erlang?
Also, how can I keep track of all the processes that the generator has created?
Upvotes: 4
Views: 299
Reputation: 7836
Okay. Now, for purposes of learning, lets do a very basic example. Others will talk of OTP Supervisors, Process dictionaries
e.t.c. but i want to keep it easy for learning purposes. With tis example, the generator can know how many processes it has created, their Pids
, knows when they die e.t.c.
-module(generator). -compile(export_all). -define(ERROR(X),error_logger:error_report(X)).Testing in shell
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.
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>A process registered as
generator
is started and may be told to start any number of children processes. The child process is generically created from the {M, F, A}
combination sent to the generator
. The generator loop keeps a track record of the processes created. It can then be told to broadcast messages to all processes.generator
loop may consume lots of memory as the list Buffer
grows since thats where we keep all the Pids
of our processes. You can also use ETS Tables
, or Mnesia
e.t.c but i havenot used them in the example because they will seem a little bit more advanced. Look at this question and its answer to understand more.
Upvotes: 4
Reputation: 1947
You can check: http://www.erlang.org/doc/design_principles/des_princ.html In terms os Erlang "Generator" was a "Supervisor"
Upvotes: 1