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