Skip to content

Latest commit

 

History

History
80 lines (69 loc) · 3.5 KB

File metadata and controls

80 lines (69 loc) · 3.5 KB

Chain.counter/1 各プロセスが実行する関数 プロセス生成時に次のプロセスのPIDを保持している メッセージを受け取ったら、次のプロセスに n + 1 の結果を送る

Chain.create_processes/1

  1. Enum.reduce/3 でやっていること
    • n個のプロセスを作り、最後に作ったプロセスのPIDを返す
    • 各プロセスに次に呼び出すプロセスのPIDを持たせている
  2. 最後に作ったプロセスに n = 0 としてメッセージを送信
  3. 結果を待つ

Enum.reduce(enumerable, acc, fun) acc を初期値として fun(element, acc) を実行し、その結果を次の acc として使用する

receive ブロックでもガード節が使える

:timer.tc(module, function, arguments) module の関数 function を引数として arguments を渡して実行し、以下のtupleを返す `{かかった時間(ミリ秒), 処理結果}

goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10)"
{9542, "Result is 10"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10)"
{4376, "Result is 10"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10)"
{4381, "Result is 10"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(100)"
{5431, "Result is 100"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(100)"
{6868, "Result is 100"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(100)"
{5568, "Result is 100"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(1000)"
{14834, "Result is 1000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(1000)"
{15233, "Result is 1000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(1000)"
{16389, "Result is 1000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10000)"
{110738, "Result is 10000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10000)"
{109732, "Result is 10000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(10000)"
{103310, "Result is 10000"}
goh@goh% elixir -r spawn/chain.ex -e "Chain.run(400000)"

15:58:58.830 [error] Too many processes


** (SystemLimitError) a system limit has been reached
    :erlang.spawn(Chain, :counter, [#PID<0.90.8>])
    spawn/chain.ex:12: anonymous fn/2 in Chain.create_processes/1
    (elixir) lib/enum.ex:2967: Enum.reduce_range_inc/4
    spawn/chain.ex:10: Chain.create_processes/1
    (stdlib) timer.erl:197: :timer.tc/3
    spawn/chain.ex:26: Chain.run/1
    (stdlib) erl_eval.erl:677: :erl_eval.do_apply/6
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(400000)"
{3966479, "Result is 400000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(400000)"
{3900263, "Result is 400000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(400000)"
{3798163, "Result is 400000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(1000000)"
{8905634, "Result is 1000000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(1000000)"
{8781462, "Result is 1000000"}
goh@goh% elixir --erl "+P 1000000" -r spawn/chain.ex -e "Chain.run(1000000)"
{8554100, "Result is 1000000"}

実行時間 >> 起動時間 ならば、実行時間はプロセス数に比例する

各プロセスは状態を持つことができる ≒ オブジェクト指向システムのオブジェクト => ココまでの説明では、プロセスを生成する単位が関数なので、オブジェクトというよりは、クロージャー同士が通信しているようなイメージが浮かんだ メッセージをやりとりするから「オブジェクトに似ている」ということなのだろうか?