You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程调用system()报错Resource temporarily unavailable,如何定位资源类型?

定位system()调用资源不足的具体类型

1. 打印具体错误码(errno)

perror仅输出错误描述,无法直接定位资源类型,修改代码打印errno的具体数值和对应说明:

#include <string.h>
#include <stdio.h>

// ... 其他代码

void* thread_func(void* arg)
{
  if (system("test.sh") == -1)
  {
    fprintf(stderr, "system调用失败,errno: %d (%s)\n", errno, strerror(errno));
    perror("system");
    exit(1);
  }
  pthread_exit(NULL);
}

不同errno对应不同资源问题:

  • EAGAIN:通常是fork()失败,可能是进程数、内存、文件描述符等资源不足;
  • ENOMEM:内存不足,无法为子进程分配页表或内存空间。

2. 检查资源限制配置

进程级限制

查看当前进程的资源限制(替换<PID>为主进程ID):

cat /proc/<PID>/limits

重点关注以下项:

  • Max processes:3000个线程同时调用system()会生成3000个子进程,需确保该值大于当前进程数+3000;
  • Max open files:每个子进程至少占用3个文件描述符(stdin/stdout/stderr),3000个子进程会占用近9000个描述符,需确认该值和系统级限制足够;
  • Max virtual memory/Max memory size:大量进程的页表等开销也可能触发内存限制。

系统级限制

查看系统全局资源限制:

# 查看系统最大PID数
cat /proc/sys/kernel/pid_max
# 查看系统最大打开文件数
cat /proc/sys/fs/file-max
# 查看当前shell生效的用户进程数限制
ulimit -u

3. 实时监控资源使用

运行程序时,用以下命令实时观察资源变化:

  • 监控进程数和内存:
top

关注Tasks栏的总进程数,Mem/Swap栏的使用率;

  • 监控系统资源统计:
vmstat 1

关注r(等待运行的进程数)、b(不可中断睡眠的进程数)、si/so(交换分区读写),若si/so持续非零,说明内存不足;

  • 监控总打开文件数:
watch -n 1 'lsof | wc -l'

对比系统的fs.file-max值,若接近则是文件描述符不足。

4. 排查fork()失败的根源

system()内部依赖fork()创建子进程,fork()失败是报错的直接原因,常见触发场景:

  • 用户进程数超限:需确认之前调整的最大进程数配置是否在当前环境生效;
  • 文件描述符耗尽:父进程若打开大量文件,加上子进程继承的描述符,可能超过限制;
  • 内存不足:fork()需要为子进程分配页表,若系统剩余内存不足以分配,会触发EAGAIN或ENOMEM。

内容的提问来源于stack exchange,提问作者user3108468

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:10:31