-module(dsquares). -export([sumsquares/1,square/0]). getNode(_) -> "127.0.0.1". %% using the same IP for all actors, %% could also be obtained from a list of IPs. totalNodes() -> 3. %% Total number of nodes (M). %% could also be read from a file. %% using 'sX@127.0.0.1' as the node name for actor N %% where X is N rem M and M is the number of nodes (up to 9). getNodeName(N) -> X = N rem totalNodes(), list_to_atom(lists:append(lists:append("s",[X+$0]), lists:append("@",getNode(N)))). sumsquares(N) -> Workers = create_actors(N), send_squares(Workers,N,self()), Sum = receive_results(N), io:format("The sum of first ~w squares is: ~w~n",[N,Sum]). create_actors(0) -> []; create_actors(N) -> [spawn(getNodeName(N),dsquares,square,[])|create_actors(N-1)]. send_squares([],_,_) -> true; send_squares([Worker|Workers], N, Farmer) -> Worker!{Farmer,N}, send_squares(Workers,N-1,Farmer). receive_results(N) -> receive_results_aux(N,0). receive_results_aux(0,Acc) -> Acc; receive_results_aux(N,Acc) -> receive S -> receive_results_aux(N-1,Acc+S) end. square() -> receive {Farmer,N} -> io:format("Computing square of: ~w at node ~w~n",[N,node()]), Farmer!N*N end. %% Usage: %% Start M nodes as: %% % erl -name s0@127.0.0.1 %% % erl -name s1@127.0.0.1 %% % ... %% % erl -name s(M-1)@127.0.0.1 %% Start sum of squares node as: %% % erl -name ss@127.0.0.1 %% (ss@127.0.0.1)1> dsquares:sumsquares(N).