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

C++中popen()执行20GB文件下载仅完成11GB的问题求助

问题:popen执行下载命令中途终止,system可正常完成

我在C++中使用popen()执行外部命令getdata -g <dataName>,该命令通过Python Socket从服务器下载文件。但文件下载至约11640016384字节时,子进程被终止退出,而原文件大小约为20GB。

popen实现代码

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout<< popen("getdata -g <dataName>", "r") << endl;
} 

执行过程及报错信息

userID@Hostname$ g++ execute_system_popen.cpp -o execute_system_popen
userID@Hostname$ ./execute_system_popen 
0x15aeeb0
userID@Hostname$ ls -Traceback (most recent call last):
  File "<string>", line 1, in <module>
BrokenPipeError: [Errno 32] Broken pipe
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='ANSI_X3.4-1968'>
BrokenPipeError: [Errno 32] Broken pipe
l fileName.tar 
-rw-r-----. 1 userID xxx **11640016384** Jan 26 23:04 fileName.tar
userID@Hostname$ 

system实现代码(可正常下载)

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout<< system("getdata -g <dataName>") << endl;
}

原因分析

popen()创建子进程后会建立管道,连接子进程的标准输出/输入与父进程。你的代码调用popen()后直接输出文件描述符地址,随后父进程main函数执行完毕直接退出,此时父进程会关闭管道的一端。子进程的getdata命令还在运行并依赖管道存在,管道关闭后子进程会收到SIGPIPE信号,触发BrokenPipeError并终止,导致下载中断。

而system()会一直等待子进程执行完毕才返回,父进程不会提前退出,管道始终保持打开,因此子进程能完成整个下载过程。

解决方法

  • 保存popen()返回的文件指针,调用pclose()等待子进程结束:
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

int main()
{
    FILE* pipe = popen("getdata -g <dataName>", "r");
    if (pipe != nullptr) {
        // 即使不需要读取输出,也必须调用pclose等待子进程完成
        int status = pclose(pipe);
        cout << "子进程退出状态: " << status << endl;
    } else {
        cerr << "popen调用失败" << endl;
        return 1;
    }
    return 0;
}
  • 若不需要捕获子进程的输出,也可以用"w"模式打开管道(减少子进程写管道触发SIGPIPE的概率),但核心要求不变:必须调用pclose()等待子进程执行完毕。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 18:35:14