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

Linux环境循环调用popen执行命令返回NULL问题求助

问题成因

  • 核心问题为文件描述符泄漏:你编写的get_system_value函数中,pclose(fp)写在了return value语句之后,属于永远不会被执行的死代码。每次调用popen都会为进程分配新的文件描述符和对应的管道资源,Linux系统对单进程最大打开文件数存在默认限制(通常为1024),程序运行几分钟后累积的未关闭文件描述符超过上限,popen无法分配新的资源就会返回NULL。
  • 存在未定义行为隐患:函数开头对未初始化的野指针fp直接调用fflush(fp),可能触发随机崩溃或者异常状态。
  • 逻辑鲁棒性不足:while(fgets(...) != NULL)循环读取所有输出行后没有判空,如果命令输出为空,atoi会直接基于缓冲区的垃圾值计算结果,没有错误处理。

解决方案

1. 修复资源泄漏核心问题

调整代码执行顺序,确保所有分支都能正常关闭popen打开的文件指针,同时删除非法的fflush调用,优化后代码如下:

unsigned int get_system_value(char *command)
{
    FILE *fp;
    char value_string[1024] = {0}; // 初始化缓冲区避免垃圾值
    fp = popen(command, "r");
    if (fp == NULL) {
        printf("Failed to execute command: %s\n", command);
        return (unsigned int)-1;
    }

    // 读取命令输出
    if (fgets(value_string, sizeof(value_string), fp) == NULL) {
        pclose(fp); // 读取失败也要先关闭指针再返回
        printf("Failed to read command output\n");
        return 0;
    }
    unsigned int value = atoi(value_string);
    pclose(fp); // 移动到return之前,保证资源释放
    return value;
}

2. 可选性能优化

你当前的实现每次读取CPU使用率都需要fork子进程、启动shell、执行外部工具,开销较大。可以直接读取解析/proc/stat文件计算CPU使用率,不需要调用外部命令,稳定性和性能都会明显提升:

  • 间隔1秒两次读取/proc/stat中cpu行的用户态、内核态、空闲时间等参数,通过两次采样的差值计算CPU使用率即可。

3. 验证方法

如果需要确认问题根因,可以执行ulimit -n查看当前系统的单进程最大打开文件数限制,程序运行时执行ls -l /proc/[你的程序PID]/fd | wc -l统计进程打开的文件描述符数量,修复后该数值会稳定在低位,不会持续上涨。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 14:54:05