Linux:-bash: fork: retry: Resource temporarily unavailable

执行命令失败,报错:


原因:

在执行命令 x 过程中有对系统内核提出资源申请,而当前用户占用的某种资源已达到系统限定上限,资源不足。


复现:

当前 Shell 资源限制:

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void *threadRun(void *arg)
{
    sleep(60 * 3);
}

int main()
{
    int num = 0;
    pthread_t tid;
    while (pthread_create(&tid, NULL, threadRun, NULL) == 0)
        printf("create thread(%llu) %d OK.\n", tid, ++num);

    sleep(60 * 3);

    return 0;
}

编译:

[test1280@localhost ~]$ gcc -o main main.c -lpthread

测试:

1.打开两个 Shell 窗口,在其中一个窗口中执行 main 程序,输出如下:

2.在另外一个已打开的窗口中执行非 Shell 内部命令(例如 ls、grep 等),可以观察到:

理由:

上面代码的功能是不断地创建线程,直到创建失败。每个创建的线程都要挂起 3 分钟,以保证同一时刻有大量线程存在。

max user processes(ulimit -u) 的含义为:The maximum number of processes available to a single user.

也就是说,此资源限制某用户同一时刻可以创建的 processes 的数量。

注:

关于 processes 的解释,大部分人解释为“进程”,但实际此处验证可得,用“线程”来解释更为合理:

max user processes 限制某用户同一时刻运行的线程最大数量。

由于 Shell max user processes 的限制,当前用户(test1280)最大同时拥有线程数量上限是 1024。

虽然其他资源充裕,但是不断地申请内核资源创建线程运行,最终达到内核上限。

在另一个 Shell 中执行非内部命令时必将有 fork 调用。

而 fork 调用必将创建一个主线程,由于资源不足无法创建线程进而导致 fork 失败,资源不可达,命令执行失败。

注:

内部命令指的是 pwd、cd 之类的命令,是 Shell 进程本身执行的命令,不必创建新进程。

外部命令(非内部命令)是 ls、grep 之类的命令,是一个可执行文件。

Shell 中执行外部命令,需先 fork 创建子 Shell 进程,然后子 Shell进程中 exec 替换为外部可执行文件,完成命令。


结论:

理论上,ulimit 限制的各类系统资源,当任一资源不足时都可能会导致 fork 调用失败,命令执行失败。

例如:

open files
max memory size
max user processes
……

附录:

如何查看当前用户所拥有的线程数量?

ps -efL | grep test1280 | wc -l

main 程序是在 test1280 账户下运行的,但我的 ps 命令是在 root 账户下执行的,因为 ps 也是外部命令呀!

关于 ulimit 系统资源限制,还请移步参考:

https://blog.csdn.net/test1280/article/details/80465082

^_^

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐