my_supervisor.erl
my_supervisor.erl — 2.1 KB
Continguts del fitxer
-module(my_supervisor). -export([start_link/2, stop/1, add_children/2, list_children/1]). -export([init/1]). start_link(Name, ChildSpecList) -> register(Name, spawn_link(my_supervisor, init, [ChildSpecList])), ok. init(ChildSpecList) -> process_flag(trap_exit, true), loop(start_children(ChildSpecList)). start_children([]) -> []; start_children([{M, F, A} | ChildSpecList]) -> case (catch apply(M,F,A)) of {ok, Pid} -> [{Pid, {M,F,A}}|start_children(ChildSpecList)]; _ -> start_children(ChildSpecList) end. add_children(Name, Children) -> Name ! {add, Children}. list_children(Name) -> Name!list. %% El bucle del supervisor espera en una recepci la clausula de sortida i els missatges de detenci. %% Si un fill acaba, el supervisor rep el seu senyal de sortida i el reinicia, i substitueix la seva %% entrada a la llista dels fills emmagatzemats a la variable ChildList: restart_child(Pid, ChildList) -> {value, {Pid, {M,F,A}}} = lists:keysearch(Pid, 1, ChildList), {ok, NewPid} = apply(M,F,A), [{NewPid, {M,F,A}}|lists:keydelete(Pid,1,ChildList)]. loop(ChildList) -> receive {add, [{M,F,A}]} -> {ok, NewPid} = apply(M,F,A), loop([{NewPid, {M,F,A}}|ChildList]); list -> io:format('Fills .=~n'), llist_children(ChildList), loop(ChildList); {'EXIT', Pid, _Reason} -> NewChildList = restart_child(Pid, ChildList), loop(NewChildList); {stop, From} -> From ! {reply, terminate(ChildList)} end. %% Es pot aturar el supervisor amb la funci de client sincrn stop/1. En rebre el missatge d'aturada, %% el supervisor executa la funci 'terminate' tota la llista de la Variable ChildList, finalitzant tots %% els fill un per un. Desprs d'haver acabat tots els fills, retorna l'tom 'ok'al procs que l'ha cridat: stop(Name) -> Name ! {stop, self()}, receive {reply, Reply} -> Reply end. terminate([{Pid, _} | ChildList]) -> exit(Pid, kill), terminate(ChildList); terminate(_ChildList) -> ok. llist_children([]) -> ok; llist_children([Child|ChildList]) -> io:format('~p~n',[Child]), llist_children(ChildList).