Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # From Dave Thomas's book: Programming Elixir
- # Execute with: elixir --erl "+P 1000000" -r chain.exs -e "Chain.run(1_000_000)"
- defmodule Chain do
- # This code will be executed in multiple processes
- # It is passed the PID of the next process in the chain.
- # When it receives a number, it increments it and sends it
- # on to that next process
- def counter(next_pid) do
- receive do
- n ->
- send next_pid, n + 1
- end
- end
- # It spawns the processes. Each one jas to passed the
- # PID of the previous process so that it knows who
- # to send the updated number to
- def create_processes(n) do
- # This variable contains the code that will
- # create the processes. This is a functions
- # that takes 2 parameters because we're passing it to
- # Enum.reduce/3.
- code_to_run = fn (_, send_to) ->
- # We spawn a new process that runs the
- # counter function, using the third parameter of
- # spawn to pass in the accumulator's current value
- # (initially self). The value returned is the PID
- # of the newly created process, which becomes the accumulator's
- # value for the next iteration.
- spawn(Chain, :counter, [send_to])
- end
- # The reduce call will iterate over the range 1..n. Each
- # time around, it will pass an accumulator as the
- # second paramenter to its function. We set the initial
- # value of that accumulator to self (the current PID).
- # The value that reduce returns is the accumulator's final
- # value, which is the PID of the last process created.
- last = Enum.reduce(1..n, self(), code_to_run)
- # We set the ball running by passing 0 to the last process.
- # It increments the value and so passes 1 to the second to
- # to last process. This goes on until the very first
- # process we created passes the result back to us.
- send(last, 0)
- # We use the recieve block to capture this,
- # and format the result.
- receive do
- final_answer when is_integer(final_answer) ->
- "Result is #{inspect(final_answer)}"
- end
- end
- # We initialize everything here using the built-in
- # Erlang lib, tc, which can time a function's execution.
- def run(n) do
- :timer.tc(Chain, :create_processes, [n]) |> IO.inspect
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement