Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.24 KB | None | 0 0
  1. # From Dave Thomas's book: Programming Elixir
  2. # Execute with: elixir --erl "+P 1000000" -r chain.exs -e "Chain.run(1_000_000)"
  3.  
  4. defmodule Chain do
  5. # This code will be executed in multiple processes
  6. # It is passed the PID of the next process in the chain.
  7. # When it receives a number, it increments it and sends it
  8. # on to that next process
  9. def counter(next_pid) do
  10. receive do
  11. n ->
  12. send next_pid, n + 1
  13. end
  14. end
  15.  
  16. # It spawns the processes. Each one jas to passed the
  17. # PID of the previous process so that it knows who
  18. # to send the updated number to
  19. def create_processes(n) do
  20.  
  21. # This variable contains the code that will
  22. # create the processes. This is a functions
  23. # that takes 2 parameters because we're passing it to
  24. # Enum.reduce/3.
  25. code_to_run = fn (_, send_to) ->
  26.  
  27. # We spawn a new process that runs the
  28. # counter function, using the third parameter of
  29. # spawn to pass in the accumulator's current value
  30. # (initially self). The value returned is the PID
  31. # of the newly created process, which becomes the accumulator's
  32. # value for the next iteration.
  33. spawn(Chain, :counter, [send_to])
  34.  
  35. end
  36.  
  37. # The reduce call will iterate over the range 1..n. Each
  38. # time around, it will pass an accumulator as the
  39. # second paramenter to its function. We set the initial
  40. # value of that accumulator to self (the current PID).
  41. # The value that reduce returns is the accumulator's final
  42. # value, which is the PID of the last process created.
  43. last = Enum.reduce(1..n, self(), code_to_run)
  44.  
  45. # We set the ball running by passing 0 to the last process.
  46. # It increments the value and so passes 1 to the second to
  47. # to last process. This goes on until the very first
  48. # process we created passes the result back to us.
  49. send(last, 0)
  50.  
  51. # We use the recieve block to capture this,
  52. # and format the result.
  53. receive do
  54. final_answer when is_integer(final_answer) ->
  55. "Result is #{inspect(final_answer)}"
  56. end
  57. end
  58.  
  59.  
  60. # We initialize everything here using the built-in
  61. # Erlang lib, tc, which can time a function's execution.
  62. def run(n) do
  63. :timer.tc(Chain, :create_processes, [n]) |> IO.inspect
  64. end
  65.  
  66.  
  67.  
  68. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement