Api Demo | 接口原型

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

2021-07-21T08:47:44
--------------------------------------------------------------------------------------------------------

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

测试:


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

————————————————

版权声明:本文为CSDN博主「test1280」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/test1280/article/details/81488500