Erlang (programming language)/Tutorials: Difference between revisions
Jump to navigation
Jump to search
imported>Eric Evers |
imported>Eric Evers |
||
Line 8: | Line 8: | ||
===Hello World (parallel)=== | ===Hello World (parallel)=== | ||
===Prime Sieve (parallel with linda type coordination)=== | ===Prime Sieve (parallel with linda type coordination)=== | ||
-module(primes). | |||
-copyright(' Gnu version 3 (c) 2008 Eric Evers'). | |||
% This is a simple linda tuplespace. Here we use it to find primes numbers. | |||
% This tuple-space can not have duplicate tuples, but with a prime sieve it does | |||
% not matter. | |||
-compile(export_all). | |||
start() -> start(100). % defualt value for max is 100 | |||
start(Max) -> | |||
io:format(" Loading ~w numbers into matrix (+N) \n ", [ Max ] ), | |||
Lid = spawn_link( primes, linda, [Max, [], [] ]), | |||
Sqrt = round(math:sqrt(Max)+0.5), | |||
io:format(" Sqrt(~w) + 1 = ~w \n " , [Max,Sqrt] ), | |||
io:format(" Tuple space is started ~n ",[]), | |||
io:format(" ~w sieves are spawning (+PN) ~n ", [Sqrt] ), | |||
io:format(" Non prime sieves are being halted (-PN) ~n ", [] ), | |||
% load numbers into tuplespace | |||
% and spawn seive process | |||
spawn( primes, put_it, [Max, Max, Lid] ). | |||
sleep(N) -> | |||
receive | |||
after N -> time_is_up | |||
end. | |||
start_sieves(Lid) -> | |||
Lid ! {self(), get, all, pids}, | |||
receive | |||
{lindagram, pids, Pids} -> done | |||
end, | |||
start_sieve_loop(Pids). | |||
start_sieve_loop([]) -> done; | |||
start_sieve_loop([Pid|Pids]) -> | |||
receive | |||
after 100 -> done | |||
end, | |||
Pid ! {start}, | |||
start_sieve_loop(Pids). | |||
spawn_sieves( _Max, Sqrt, _Lid, Sqrt ) -> done; | |||
spawn_sieves( Max, Inc, Lid, Sqrt ) -> | |||
T = 1000, | |||
Pid = spawn( primes, sieve, [ Max, Inc+Inc, Inc, Lid, T ]), | |||
Name = list_to_atom("P" ++ integer_to_list(Inc)), | |||
Lid ! {put, pid, Name}, | |||
register( Name, Pid), | |||
io:format(" +~s ", [atom_to_list(Name)]), | |||
spawn_sieves( Max, Inc+1, Lid, Sqrt ). | |||
put_it(Max, N, Lid) when N =< 1 -> | |||
Sqrt = round(math:sqrt(Max)+0.5), | |||
spawn_sieves( Max, 2, Lid, Sqrt ); | |||
put_it(Max, N,Lid) when N > 1 -> | |||
receive | |||
after 0 -> | |||
Lid ! {put, N, N}, | |||
if | |||
N rem 1000 == 0 -> | |||
io:format(" +~w ", [N]); | |||
true -> done | |||
end, | |||
put_it(Max, N-1,Lid) | |||
end. | |||
% the 2 sieve starts last and has the most to do so it finishes last | |||
sieve(Max, N, 2, Lid, _T) when N > Max -> | |||
io:format("final sieve ~w done, ~n", [2] ), | |||
Lid ! {dump,output}; | |||
sieve(Max, N, Inc, _Lid, _T) when N > Max -> | |||
io:format("sieve ~w done ", [Inc] ); | |||
sieve(Max, N, Inc, Lid, T) when N =< Max -> | |||
receive | |||
after | |||
T -> NT = 0 | |||
end, | |||
receive | |||
{lindagram,Number} when Number =/= undefined -> | |||
clearing_the_queue; | |||
{exit} -> exit(normal) | |||
after | |||
1 -> done | |||
end, | |||
% remove multiple of number from tuple-space | |||
Lid ! {self(), get, N}, | |||
Some_time = (N rem 1000)==0, | |||
if Some_time -> io:format("."); true -> done end, | |||
% remove (multiple of Inc) from sieve-process space | |||
Name = list_to_atom("P" ++ integer_to_list(N)), | |||
Exists = lists:member( Name, registered()), | |||
if | |||
Exists -> | |||
Name ! {exit}, | |||
io:format(" -~s ", [atom_to_list(Name)] ); | |||
true -> done | |||
end, | |||
sieve(Max, N+Inc, Inc, Lid, NT). % next multiple | |||
%% linda is a simple tutple space | |||
%% if it receives no messages for 2 whole seconds it dumps its contents | |||
%% as output and halts | |||
linda(Max, Keys, Pids) -> | |||
receive | |||
{put, pid, Pid} -> | |||
linda(Max, Keys, Pids++[Pid]); | |||
{put, Name, Value} -> | |||
put( Name, Value), | |||
linda(Max, Keys++[Name], Pids); | |||
{From, get, Name} -> | |||
From ! {lindagram, get( Name)}, | |||
erase( Name ), % get is a desructive read | |||
linda(Max, Keys--[Name],Pids); | |||
{From, get, all, pids} -> | |||
From ! {lindagram, pids, Pids}, | |||
linda(Max, Keys, Pids ); | |||
{From, get, pid, Pid} -> | |||
L1 = length( Pids ), | |||
L2 = length( Pids -- [Pid]), | |||
if | |||
L1 > L2 -> % if it exists | |||
From ! {lindagram, pid, Pid}; | |||
true -> | |||
From ! {lindagram, pid, undefined} | |||
end, | |||
linda(Max, Keys, Pids ); | |||
{dump,output} -> | |||
io:format(" ~w final primes remain: ~w ~n ", [length(Keys), lists:sort(Keys) ]) | |||
after (100*Max) -> % if there is not tuple action after some time then print the results | |||
io:format(" ~w primes remain: ~w ~n ", [length(Keys), lists:sort(Keys) ]) | |||
end. | |||
==References== | ==References== |
Revision as of 16:09, 12 April 2008
Erlang Language Programming Tutorials
Overview
Simple Types
Advanced Types
Examples
Hello World (serial)
Hello World (parallel)
Prime Sieve (parallel with linda type coordination)
-module(primes).
-copyright(' Gnu version 3 (c) 2008 Eric Evers').
% This is a simple linda tuplespace. Here we use it to find primes numbers.
% This tuple-space can not have duplicate tuples, but with a prime sieve it does
% not matter.
-compile(export_all).
start() -> start(100). % defualt value for max is 100
start(Max) -> io:format(" Loading ~w numbers into matrix (+N) \n ", [ Max ] ),
Lid = spawn_link( primes, linda, [Max, [], [] ]), Sqrt = round(math:sqrt(Max)+0.5), io:format(" Sqrt(~w) + 1 = ~w \n " , [Max,Sqrt] ),
io:format(" Tuple space is started ~n ",[]),
io:format(" ~w sieves are spawning (+PN) ~n ", [Sqrt] ),
io:format(" Non prime sieves are being halted (-PN) ~n ", [] ),
% load numbers into tuplespace
% and spawn seive process
spawn( primes, put_it, [Max, Max, Lid] ).
sleep(N) -> receive after N -> time_is_up end.
start_sieves(Lid) ->
Lid ! {self(), get, all, pids},
receive
{lindagram, pids, Pids} -> done
end,
start_sieve_loop(Pids).
start_sieve_loop([]) -> done;
start_sieve_loop([Pid|Pids]) ->
receive
after 100 -> done
end,
Pid ! {start},
start_sieve_loop(Pids).
spawn_sieves( _Max, Sqrt, _Lid, Sqrt ) -> done; spawn_sieves( Max, Inc, Lid, Sqrt ) ->
T = 1000, Pid = spawn( primes, sieve, [ Max, Inc+Inc, Inc, Lid, T ]), Name = list_to_atom("P" ++ integer_to_list(Inc)),
Lid ! {put, pid, Name},
register( Name, Pid),
io:format(" +~s ", [atom_to_list(Name)]),
spawn_sieves( Max, Inc+1, Lid, Sqrt ).
put_it(Max, N, Lid) when N =< 1 -> Sqrt = round(math:sqrt(Max)+0.5), spawn_sieves( Max, 2, Lid, Sqrt );
put_it(Max, N,Lid) when N > 1 ->
receive
after 0 ->
Lid ! {put, N, N}, if N rem 1000 == 0 ->
io:format(" +~w ", [N]); true -> done end,
put_it(Max, N-1,Lid)
end.
% the 2 sieve starts last and has the most to do so it finishes last sieve(Max, N, 2, Lid, _T) when N > Max -> io:format("final sieve ~w done, ~n", [2] ), Lid ! {dump,output};
sieve(Max, N, Inc, _Lid, _T) when N > Max -> io:format("sieve ~w done ", [Inc] );
sieve(Max, N, Inc, Lid, T) when N =< Max ->
receive
after
T -> NT = 0
end, receive {lindagram,Number} when Number =/= undefined -> clearing_the_queue;
{exit} -> exit(normal) after 1 -> done end,
% remove multiple of number from tuple-space
Lid ! {self(), get, N},
Some_time = (N rem 1000)==0,
if Some_time -> io:format("."); true -> done end,
% remove (multiple of Inc) from sieve-process space
Name = list_to_atom("P" ++ integer_to_list(N)),
Exists = lists:member( Name, registered()),
if
Exists ->
Name ! {exit},
io:format(" -~s ", [atom_to_list(Name)] );
true -> done
end,
sieve(Max, N+Inc, Inc, Lid, NT). % next multiple %% linda is a simple tutple space
%% if it receives no messages for 2 whole seconds it dumps its contents %% as output and halts
linda(Max, Keys, Pids) ->
receive
{put, pid, Pid} ->
linda(Max, Keys, Pids++[Pid]);
{put, Name, Value} ->
put( Name, Value),
linda(Max, Keys++[Name], Pids);
{From, get, Name} ->
From ! {lindagram, get( Name)},
erase( Name ), % get is a desructive read
linda(Max, Keys--[Name],Pids);
{From, get, all, pids} ->
From ! {lindagram, pids, Pids},
linda(Max, Keys, Pids );
{From, get, pid, Pid} ->
L1 = length( Pids ),
L2 = length( Pids -- [Pid]),
if
L1 > L2 -> % if it exists
From ! {lindagram, pid, Pid};
true ->
From ! {lindagram, pid, undefined}
end,
linda(Max, Keys, Pids ); {dump,output} -> io:format(" ~w final primes remain: ~w ~n ", [length(Keys), lists:sort(Keys) ])
after (100*Max) -> % if there is not tuple action after some time then print the results
io:format(" ~w primes remain: ~w ~n ", [length(Keys), lists:sort(Keys) ])
end.