user1301428
user1301428

Reputation: 1783

How to tell a process to create another process and keep track of it

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

Answers (2)

Muzaaya Joshua
Muzaaya Joshua

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)).
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.
Testing in 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>
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.

However, in practice/ production, you might not to do this, because the 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

couchemar
couchemar

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

Related Questions