Last active
December 27, 2015 09:09
-
-
Save niku/7301933 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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