过程太多,为什么?

时间:2015-01-11 21:13:37

标签: erlang

我正在尝试的问题是

  

写一个戒指基准。在环中创建N个进程。发送消息   围绕环M次,以便总共发送N * M个消息。   时间对于不同的N和M值需要多长时间。

我的尝试看起来像

-module(ring).
-author("harith").

%% API
-export([message/2, test/0]).

test() ->
  Max = erlang:system_info(process_limit),
  io:format("max processes: ~p~n", [Max]),
  Time = [timer:tc(ring, message, [N, M]) || N <- lists:seq(10, 500, 10), M <- lists:seq(1000, 100000, 1000)],
  [io:format("(~p)processes, (~p) messages, (~p) microseconds~n", [N, M, T]) || {T, {N, M}} <- Time].

% create ring of N processes and
% send M messages between them
message(N, M) when is_integer(N), is_integer(M), N > 0, M > 0 ->
  Ring = create_ring(N),
  [Start | T] = Ring,
  Start ! {T, Ring, 1, M},
  {N, M}.

create_ring(N) ->
  Processes = [spawn(fun() -> loop() end) || _ <- lists:seq(1, N)],
  [H | _] = Processes,
  lists:append(Processes, [H]).

loop() ->
  receive
    {[H | T], _L, CurrentMessage, M} ->
      % io:format("~p received ~p~n", [self(), CurrentMessage]),
      H ! {T, _L, CurrentMessage, M},
      loop();
    {[], Ring, CurrentMessage, M} ->
      % io:format("~p received ~p with empty list~n", [self(), CurrentMessage]),
      case CurrentMessage < M of
        true ->
          [_ | [Next | T]] = Ring,
          NewMessage = CurrentMessage + 1,
          % io:format("sending message ~p to ~p~n", [NewMessage, Next]),
          Next ! {T, Ring, NewMessage, M};
        false -> void %io:format("done sending ~p messages in ~p ring, taking rest now.~n", [M, Ring])
      end,
      loop()
  end.

问题吗
当我测试此代码时,它失败并出现以下错误

1> c(ring).
{ok,ring}
2> ring:test().
max processes: 262144

=ERROR REPORT==== 11-Jan-2015::12:59:24 ===
Too many processes

** exception error: a system limit has been reached
     in function  spawn/3
        called as spawn(erlang,apply,[#Fun<ring.0.102056517>,[]])
     in call from spawn/1 
     in call from ring:'-create_ring/1-lc$^0/1-0-'/1 (ring.erl, line 30)
     in call from ring:'-create_ring/1-lc$^0/1-0-'/1 (ring.erl, line 30)
     in call from ring:create_ring/1 (ring.erl, line 30)
     in call from ring:message/2 (ring.erl, line 24)
     in call from timer:tc/3 (timer.erl, line 194)
     in call from ring:'-test/0-lc$^1/1-1-'/3 (ring.erl, line 18)
*** ERROR: Shell process terminated! ***

=ERROR REPORT==== 11-Jan-2015::12:59:24 ===
Too many processes


=ERROR REPORT==== 11-Jan-2015::12:59:24 ===
Error in process <0.26.0> with exit value: {system_limit,[{erlang,spawn_link,[erlang,apply,[#Fun<shell.1.95205691>,[]]],[]},{erlang,spawn_link,1,[]},{shell,get_command,5,[{file,"shell.erl"},{line,298}]},{shell,server_loop,7,[{file,"shell.erl"},{line,229}]}]}

Eshell V6.2  (abort with ^G)
*** ERROR: Shell process terminated! ***

=ERROR REPORT==== 11-Jan-2015::12:59:25 ===
Too many processes


=ERROR REPORT==== 11-Jan-2015::12:59:25 ===
Error in process <0.32.16> with exit value: {system_limit,[{erlang,spawn_link,[erlang,apply,[#Fun<shell.1.95205691>,[]]],[]},{erlang,spawn_link,1,[]},{shell,get_command,5,[{file,"shell.erl"},{line,298}]},{shell,server_loop,7,[{file,"shell.erl"},{line,229}]}]}


User switch command
 --> 

嗯,我的数学不是很好,但我仍然做了以下数学运算,看看是否真的如此。
我试着看看我的程序创建了多少个进程,这些进程直接将我链接到N

Time = [timer:tc(ring, message, [N, M]) || N <- lists:seq(10, 500, 10), M <- lists:seq(1000, 100000, 1000)],

我试图从

中找出整数之和
10, 20, 30, ...., 500  

,差异为10

我试图在序列中找出n = number of terms
enter image description here
n=50

的结果为a1 = 10, an = 500, d = 10

我发现总和为 enter image description here

原来是(10 + 500)*50/2 12750 ,并根据记录可以创建的最大进程

max processes: 262144

有人可以帮我理解这个问题吗?

由于

1 个答案:

答案 0 :(得分:3)

你的数字是12750是正确的。但是你在这个列表理解中给ring:message/2打了个电话:

[timer:tc(ring, message, [N, M]) || N <- lists:seq(10, 500, 10), M <- lists:seq(1000, 100000, 1000)]

修改它不做任何事情并计算其长度,然后将该长度乘以12750得到:

1> length([x || N <- lists:seq(10, 500, 10), M <- lists:seq(1000, 100000, 1000)]).
5000
2> 12750*5000.
63750000

当然远高于默认的最大处理限制262144。