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
相关产品推荐
相关产品推荐

