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

