更改 Erlang 文件句柄限制?
Change Erlang file handle limit?
我 运行 遇到了 Erlang OTP + Cowboy 应用程序的问题,该应用程序不允许我同时打开足够多的文件。
如何更改 BEAM 中允许的打开文件句柄数?
我可能需要同时打开大约 500 个小文本文件,但文件限制似乎是 224。我从这个小测试程序中得到了 224 的值:
-module(test_fds).
-export([count/0]).
count() -> count(1, []).
count(N, Fds) ->
case file:open(integer_to_list(N), [write]) of
{ok, F} ->
count(N+1, [F| Fds]);
{error, Err} ->
[ file:close(F) || F <- Fds ],
delete(N-1),
{Err, N}
end.
delete(0) -> ok;
delete(N) ->
case file:delete(integer_to_list(N)) of
ok -> ok;
{error, _} -> meh
end,
delete(N-1).
这给了
$ erl
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [kernel-poll:false]
Eshell V9.2 (abort with ^G)
1> c(test_fds).
{ok,test_fds}
2> test_fds:count().
{emfile,224}
3>
这似乎是一个 Erlang 问题而不是 Mac OSX 问题,因为从命令行,我得到:
$ sysctl -h kern.maxfiles
kern.maxfiles: 49,152
$ sysctl -h kern.maxfilesperproc
kern.maxfilesperproc: 24,576
打开文件描述符的数量很可能受到您的限制 shell。在调用 erl
之前,您可以在 shell 中将其增加 运行 ulimit -n 1000
(或更多)。在我的系统上,默认值为 7168,您的脚本在返回 emfile
之前可以打开 7135 个文件。这是我 运行 你的脚本的输出,具有不同的 ulimit
值:
$ ulimit -n 64; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,32}
$ ulimit -n 128; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,96}
$ ulimit -n 256; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,224}
$ ulimit -n 512; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,480}
erl
很可能在开始评估我们的代码之前打开 32 个文件描述符,这解释了 ulimit
和输出中 32 的常量差异。
我 运行 遇到了 Erlang OTP + Cowboy 应用程序的问题,该应用程序不允许我同时打开足够多的文件。
如何更改 BEAM 中允许的打开文件句柄数?
我可能需要同时打开大约 500 个小文本文件,但文件限制似乎是 224。我从这个小测试程序中得到了 224 的值:
-module(test_fds).
-export([count/0]).
count() -> count(1, []).
count(N, Fds) ->
case file:open(integer_to_list(N), [write]) of
{ok, F} ->
count(N+1, [F| Fds]);
{error, Err} ->
[ file:close(F) || F <- Fds ],
delete(N-1),
{Err, N}
end.
delete(0) -> ok;
delete(N) ->
case file:delete(integer_to_list(N)) of
ok -> ok;
{error, _} -> meh
end,
delete(N-1).
这给了
$ erl
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [kernel-poll:false]
Eshell V9.2 (abort with ^G)
1> c(test_fds).
{ok,test_fds}
2> test_fds:count().
{emfile,224}
3>
这似乎是一个 Erlang 问题而不是 Mac OSX 问题,因为从命令行,我得到:
$ sysctl -h kern.maxfiles
kern.maxfiles: 49,152
$ sysctl -h kern.maxfilesperproc
kern.maxfilesperproc: 24,576
打开文件描述符的数量很可能受到您的限制 shell。在调用 erl
之前,您可以在 shell 中将其增加 运行 ulimit -n 1000
(或更多)。在我的系统上,默认值为 7168,您的脚本在返回 emfile
之前可以打开 7135 个文件。这是我 运行 你的脚本的输出,具有不同的 ulimit
值:
$ ulimit -n 64; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,32}
$ ulimit -n 128; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,96}
$ ulimit -n 256; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,224}
$ ulimit -n 512; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,480}
erl
很可能在开始评估我们的代码之前打开 32 个文件描述符,这解释了 ulimit
和输出中 32 的常量差异。