【问题标题】:Fork fails with "resource temporarily unavailable". Which resource?Fork 因“资源暂时不可用”而失败。哪个资源?
【发布时间】:2017-05-20 02:20:18
【问题描述】:

我继承了一个 Perl 脚本,根据机器配置,该脚本在使用 $? == 11 调用 fork 时失败。

根据errno.hvariousposts,11是EAGAIN,即“再试一次”,因为某些资源暂时不可用。

有没有办法确定是哪个资源导致分叉失败, 除了一一增加各种系统限制 (open file descriptors, swap space,或 allowable threads) 的数量?

【问题讨论】:

  • 分叉进程是原始进程的完整克隆。在 fork 之前分析你的进程将让你知道它使用了多少资源。
  • 你的意思是 $!=11?
  • Do you mean $!=11?。其实,我有点说错了。我应该说的是,fork 是成功的,但立即以状态码 11 结束,正如 wait 所报告的那样。
  • 所以你的问题与fork无关,那你为什么接受我的回答,完全是关于fork在失败时设置的errno???

标签: perl fork ulimit


【解决方案1】:

假设您的意思是 $!EAGAIN,我系统上的 fork 手册页显示:

EAGAIN:fork() 无法分配足够的内存来复制父级的页表并为子级分配任务结构。

EAGAIN:无法创建新进程,因为遇到调用者的 RLIMIT_NPROC 资源限制。要超过此限制,进程必须具有 CAP_SYS_ADMIN 或 CAP_SYS_RESOURCE 功能。

您是否正在尝试创建大量流程?孩子们完成后你会收割他们吗?

【讨论】:

  • 请参阅我上面的评论以澄清原始问题,这对我来说过于简单化了。真正的事件顺序如下:初始化后,程序通过调用 system() 来预处理一个大文件(8Gb)。然后程序为机器上的每个 cpu 核心分叉一个进程。因此,该程序可能会在分叉时尝试复制一个非常大的内存空间(但是 linux 是 copy-write,所以应该可以吗?)。有大量 RAM (184Gb),我提高了允许打开的文件数并增加了交换空间。
  • 有些fork成功,有些失败,如果我限制整体fork的数量,那么我经常可以让程序正常运行。
  • Re "fork 成功", & "有的fork 有的成功有的没有",是哪一个?什么呼叫呼叫失败?你为什么不检查它失败的错误?
【解决方案2】:

该错误是由于用户已用完可用堆栈。 检查 RHEL 服务器上的安全配置文件 [root@server1 webapps]# cat /etc/security/limits.d/90-nproc.conf

# Default limit for number of user's processes to prevent

# accidental fork bombs.

# See rhbz #432903 for reasoning.

* soft nproc 1024

root soft nproc unlimited

[root@server1 webapps]# vi /etc/security/limits.d/90-nproc.conf

[root@server1 webapps]#

在我的例子中,“测试”用户收到消息“-bash: fork: retry: Resource暂时不可用”

通过添加用户特定的堆栈限制来解决问题

[root@server1 webapps]# vi/etc/security/limits.d/90-nproc.conf

# Default limit for number of user's processes to prevent

# accidental fork bombs.

# See rhbz #432903 for reasoning.

* soft nproc 1024

test soft nproc 16384

root soft nproc unlimited

[root@server1 webapps]#

【讨论】:

    猜你喜欢
    • 2018-05-11
    • 2022-10-24
    • 2012-08-18
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 2018-08-04
    • 2021-05-07
    相关资源
    最近更新 更多