以编程方式在 OS X/MacOS 上设置 maxfile
Setting maxfile on OS X/MacOS Programmatically
如果我使用 launchctl
的 limit
命令查看 maxfiles
选项(在我的 OS X El Cap 机器上)
$ launchctl limit
cpu unlimited unlimited
filesize unlimited unlimited
data unlimited unlimited
stack 8388608 67104768
core 0 unlimited
rss unlimited unlimited
memlock unlimited unlimited
maxproc 709 1064
maxfiles 256 unlimited
似乎有 256 的软限制和 "unlimited" 的硬限制。我想将软限制更改为 2048
之类的内容,并保持硬限制不变。当我查看 limit
的参数时
$ launchctl help limit
Usage: launchctl limit [<limit-name> [<both-limits> | <soft-limit> <hard-limit>]
看来我可以将两个限制设置为同一事物,或为软和硬设置一个值。但是,如果我尝试设置无限的硬限制。
$ sudo launchctl limit maxfiles 2048 unlimited
我最终得到了奇怪的值 10240
$ launchctl limit
cpu unlimited unlimited
filesize unlimited unlimited
data unlimited unlimited
stack 8388608 67104768
core 0 unlimited
rss unlimited unlimited
memlock unlimited unlimited
maxproc 709 1064
maxfiles 2048 10240
这是怎么回事?是否可以设置无限值?如果不是,那是 launchctl limit
命令的限制,还是系统级别的限制?如果是后者,unlimited
报告的初始值是多少?或者这个苹果就是苹果?
对于奖励积分 -- 有人知道为什么这个限制首先设置得这么低吗?
Apple 在 Yosemite 中更改了这些内容,但没有推测原因。通过 launchctl limit ... 所做的任何更改仅对您当前的登录名是临时的。重新登录或重启,它们会立即返回到 Apple 设置的默认值。
我可以确认他们从 10.12.4 b4 开始还没有改变这个行为。
当 Apple 就是 Apple 时,这是一种无法令人满意的消化。我深入研究了开发人员文档,但找不到他们进行更改的原因的解释。
来自 man page for setrlimit()
,launchd
实现此功能所依赖的底层系统调用:
setrlimit()
now returns with errno
set to EINVAL
in places that historically succeeded. It no longer accepts "rlim_cur = RLIM_INFINITY
" for RLIM_NOFILE
. Use "rlim_cur = min(OPEN_MAX, rlim_max)
".
因此,虽然 getrlimit()
可能(最初)报告硬限制是 RLIM_INFINITY
,但实际上是 OPEN_MAX
(10240),因为这只是由如何施加的限制内核已实现。如果您尝试设置限制,则需要使用后一个值,这会影响从那时起报告的内容。
至于为什么RLIM_NOFILE
的软限制默认为256,是因为对于绝大多数进程来说,这不是一个实际的限制。他们在没有接近这个限制的情况下相处得很好。保持值 "so low" 意味着每个进程在内存方面的成本较低,并且每个 fork()
在将文件描述符复制到新子进程等方面的工作较少
知道自己可能会处理更多文件的程序可以使用 setrlimit()
更改自己的限制。
如果我使用 launchctl
的 limit
命令查看 maxfiles
选项(在我的 OS X El Cap 机器上)
$ launchctl limit
cpu unlimited unlimited
filesize unlimited unlimited
data unlimited unlimited
stack 8388608 67104768
core 0 unlimited
rss unlimited unlimited
memlock unlimited unlimited
maxproc 709 1064
maxfiles 256 unlimited
似乎有 256 的软限制和 "unlimited" 的硬限制。我想将软限制更改为 2048
之类的内容,并保持硬限制不变。当我查看 limit
的参数时
$ launchctl help limit
Usage: launchctl limit [<limit-name> [<both-limits> | <soft-limit> <hard-limit>]
看来我可以将两个限制设置为同一事物,或为软和硬设置一个值。但是,如果我尝试设置无限的硬限制。
$ sudo launchctl limit maxfiles 2048 unlimited
我最终得到了奇怪的值 10240
$ launchctl limit
cpu unlimited unlimited
filesize unlimited unlimited
data unlimited unlimited
stack 8388608 67104768
core 0 unlimited
rss unlimited unlimited
memlock unlimited unlimited
maxproc 709 1064
maxfiles 2048 10240
这是怎么回事?是否可以设置无限值?如果不是,那是 launchctl limit
命令的限制,还是系统级别的限制?如果是后者,unlimited
报告的初始值是多少?或者这个苹果就是苹果?
对于奖励积分 -- 有人知道为什么这个限制首先设置得这么低吗?
Apple 在 Yosemite 中更改了这些内容,但没有推测原因。通过 launchctl limit ... 所做的任何更改仅对您当前的登录名是临时的。重新登录或重启,它们会立即返回到 Apple 设置的默认值。
我可以确认他们从 10.12.4 b4 开始还没有改变这个行为。
当 Apple 就是 Apple 时,这是一种无法令人满意的消化。我深入研究了开发人员文档,但找不到他们进行更改的原因的解释。
来自 man page for setrlimit()
,launchd
实现此功能所依赖的底层系统调用:
setrlimit()
now returns witherrno
set toEINVAL
in places that historically succeeded. It no longer accepts "rlim_cur = RLIM_INFINITY
" forRLIM_NOFILE
. Use "rlim_cur = min(OPEN_MAX, rlim_max)
".
因此,虽然 getrlimit()
可能(最初)报告硬限制是 RLIM_INFINITY
,但实际上是 OPEN_MAX
(10240),因为这只是由如何施加的限制内核已实现。如果您尝试设置限制,则需要使用后一个值,这会影响从那时起报告的内容。
至于为什么RLIM_NOFILE
的软限制默认为256,是因为对于绝大多数进程来说,这不是一个实际的限制。他们在没有接近这个限制的情况下相处得很好。保持值 "so low" 意味着每个进程在内存方面的成本较低,并且每个 fork()
在将文件描述符复制到新子进程等方面的工作较少
知道自己可能会处理更多文件的程序可以使用 setrlimit()
更改自己的限制。