【发布时间】:2015-12-18 22:00:49
【问题描述】:
注意:我使用的是openFrameworks,但我认为这不是理解我的问题所必需的知识。
概述
OSX 10.8.5
XCode 5.1.1
我有一个程序fork()s,子进程运行这个cURL cmd:
curl -c cookies.txt -b cookies.txt -k https://www.space-track.org/ajaxauth/login -d 'identity=email@example.com&password=p4$$w0rd&query=https://www.space-track.org/basicspacedata/query/class/tle_latest/ORDINAL/1/EPOCH/%3Enow-30/orderby/OBJECT_ID/format/json' > ~/../myApp/bin/data/myData.json -#
这个:
- 管理Space Track API 的 cookie 文件
- 使用我的 Space Track 帐户登录
- 将数据集(约 15,000 个 json 对象)下载到“myData.json”
- 显示进度条
######################################################################## 100.0%
子进程将进度条传递给父进程,一次 1 个字符。父级同时将进度条打印到控制台。以下是我的代码的整个fork() 部分:
.h(相关的全局变量)
{
bool forkOnce, isBufferFull;
int childToParentPipe[2]; // Child to parent pipe. [0] = read (output), [1] = write (input)
char ch;
int pid, outCount;
string buffer;
}
.cpp
if(!forkOnce){ //we're in an ∞ loop, so we need to control the flow
//make pipe
if( pipe(childToParentPipe) < 0){
perror("Can't make pipe");
_exit(1);
}
//vars for dealing w piped chars
buffer = ""; // string that holds 1 line of progress meter
isBufferFull = false; // is ^ buffer string full?
outCount = 0; //counts chars coming from pipe (for carriage returns)
cout << "Forking..." << endl;
pid = fork();
}
switch(pid){
case -1:{
perror("Can't fork");
_exit(EXIT_FAILURE);
break;
}
case 0:{ // child
if(!forkOnce){ // do child stuff once
close(2); // Close current stderr
dup( childToParentPipe[1]); //Make stderr go to write end of pipe
close( childToParentPipe[0]); //Close read end of pipe because it's not needed in child process
//make output file for stdout
int out = creat("/.../myApp/bin/data/myData.json", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (out == -1){
perror("Can't make file");
_exit(EXIT_FAILURE);
} else { //if file successfully created
dup2(out,STDOUT_FILENO);// redirect stdout to the file
execlp( [the curl command goes here] , NULL); // exec the command
close(out); // close file
_exit(0);
}
}
break;
}
default:{ // parent
close(childToParentPipe[1]);
//while num bytes piped out is 1 (meaning we haven't reached EOF yet)
if( read(childToParentPipe[0], &ch, 1) == 1) {
if(outCount == 80){
isBufferFull = true;
outCount = 0;
}
if(!isBufferFull){
buffer += ch;
} else {
char* bufferChars = strdup(buffer.c_str());
bufferChars[outCount] = ch;
buffer = bufferChars;
}
cout << buffer << endl;
outCount++;
}
// wait for child process
int status = 0;
waitpid(-1, &status, WNOHANG);
//printf("child status:%d\n",status); // "0"
signal(SIGCHLD,signalHandler); //signalHandler = func that finalizes this process
break;
}
}
forkOnce = true;
问题
与在终端中运行相比,我的应用程序的 cURL 下载速度非常慢:
...有时,在我的应用程序中,此错误会在下载过程中多次打印到控制台:
2015-12-18 15:44:16.595 forkTest2Debug[22858:5f1f] -[NSPersistentUIManager writeWindowSnapshot:length:width:height:bytesPerRow:toFile:inDirectory:encryptingWithKey:uuid:checksum:isUserWaitingImpatientlyForThisThingToFinish:]: 0 == ftruncate(fd, finalFileSize) failed on line 2770: Bad file descriptor
无法弄清楚为什么我会收到 Bad file descriptor 错误。在这种情况下,我似乎找不到任何关于 isUserWaitingImpatientlyForThisThingToFinish 或 ftruncate 的官方文档。
我的应用程序以 60fps 的速度运行,因此管道的输出以该速率泵出字符。这可能会填满我的管道,因为输入字符的速度比输入的速度快吗?
是什么导致了这种缓慢,我该如何解决?
【问题讨论】:
标签: c++ unix curl pipe openframeworks