进程太多,为什么?
Too many processes, why?
我正在尝试的问题是
Write a ring benchmark. Create N processes in a ring. Send a message
round the ring M times so that a total of N * M messages get sent.
Time how long this takes for different values of N and 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
的顺序为
对于 a1 = 10, an = 500, d = 10
结果是 n=50
我发现总和为
结果是 (10 + 500)*50/2
12750 并且根据日志可以创建的最大进程数
max processes: 262144
有人可以帮助我理解这个问题吗?
谢谢
你的数字 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。
我正在尝试的问题是
Write a ring benchmark. Create N processes in a ring. Send a message round the ring M times so that a total of N * M messages get sent. Time how long this takes for different values of N and 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
的顺序为
对于 a1 = 10, an = 500, d = 10
n=50
我发现总和为
结果是 (10 + 500)*50/2
12750 并且根据日志可以创建的最大进程数
max processes: 262144
有人可以帮助我理解这个问题吗?
谢谢
你的数字 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。