erlang - 更改 Erlang 文件句柄限制?

标签 erlang file-handling beam

我遇到了 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 - 更改 Erlang 文件句柄限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49047935/

相关文章:

erlang - 如何实现一个函数来通知一个节点另一个节点是否退出

java - ALOS 卫星产品到 PNG 转换问题(缺少旋转)

erlang - 配置 Couchbase 2.2 使用短主机名

erlang - 如何创建钢筋仓库?

erlang - Ecto 的片段允许 SQL 注入(inject)

file - 如何在 Lua 中获取最后修改的时间戳

erlang - 为什么在 Erlang 中搜索众多二进制文件之一比使用 `binary:match` 只搜索一个二进制文件更快?

c - C 中的文件处理 - 从文本文件列表中删除特定单词

c++ - 在 C++ 中检测文件中的空间

erlang - 打包 Elixir CLI 应用程序的最佳方式是什么?