Skip to content

Instantly share code, notes, and snippets.

@niku
Last active December 27, 2015 09:09
Show Gist options
  • Save niku/7301933 to your computer and use it in GitHub Desktop.
Save niku/7301933 to your computer and use it in GitHub Desktop.
# from
# http://pragprog.com/book/elixir/programming-elixir
# 14 Process Overhead
defmodule Chain do
def counter(next_pid) do
# Chain.counter は,何か数値が送られてきたらその数値に1を加えて次のプロセスを呼びだす
# 数値がsendで送られてくるまでは単に待ちつづける
receive do # 3つのプロセスとも,プロセスにむけて数値がsendで送られてくるまでここで止まる
# 【3】
# 3番目のプロセスは【2】で0が送られてきたので,nに0が入って動きだす.
# 3番目のプロセスのnext_pidには2番目のプロセスが入っている.
# そこで2番目のプロセスに対して0+1,つまり1を送る.
#
# 2番目のプロセスは1が送られてきたので,nに1が入って動きだす.
# 2番目のプロセスのnext_pidには1番目のプロセスが入っている.
# そこで1番目のプロセスに対して1+1,つまり2を送る.
#
# 1番目のプロセスは2が送られてきたので,nに2が入って動きだす.
# 1番目のプロセスのnext_pidにはcreate_processesを実行しているプロセスが入っている.
# そこでcreate_processesを実行しているプロセスに対して2+1,つまり3を送る.
n ->
send next_pid, n + 1
end
end
def create_processes(n) do
# 【1】
# n = 3 だとする
# 1..n は [1, 2, 3] になる.
#
# 1つめは,create_processesを実行しているプロセス(self)を引数に,Chain.counterを実行するプロセスを作る
# 2つめは,1つめのプロセスを引数に,Chain.counterを実行するプロセスを作る
# 3つめは,2つめのプロセスを引数に,Chain.counterを実行するプロセスを作る
#
# つまり3つプロセスを作る.
# プロセスの数は「create_processesを実行しているプロセス」+3で,4つになる.
#
# Enum.reduceの返り値は最後に評価した値,つまり3番目のプロセスが返る
# そこでlastには3番目のプロセスが割り当たる
last = Enum.reduce 1..n, self,
fn (_,send_to) ->
spawn(Chain, :counter, [send_to])
end
# 【2】
# create_processesを実行しているプロセスから
# 3番目のプロセスに数値0を送る
send last, 0
# 【4】
# プロセスに数値がsendで送られてくるまでここで止まる
# 【3】の最後に,このプロセスへ3が送られてくるのでfinal_answerへ3が入って動き出す
receive do
final_answer when is_integer(final_answer) ->
"Result is #{inspect(final_answer)}"
end
# 【5】
# 最後に評価した値が返り値になるので,
# "Result is 3" という文字列が返り値になる
end
def run(n) do
IO.puts inspect :timer.tc(Chain, :create_processes, [n])
end
end
$ elixir --erl "+P 1000000" -r chain.exs -e "Chain.run(1_000_000)"
{16961375, "Result is 1000000"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment