【发布时间】:2014-09-03 23:38:47
【问题描述】:
在下面的代码之前我会这样做:
创建 1 个管道以读取分叉进程的输出
fork()
execv() 一个 python 脚本
然后在我做的父进程中:
//set pipes to non-Blocking
File * cout_f = fdopen(cout_pipe[0], "r");
int flags = fcntl(cout_pipe[0], F_GETFL, 0);
fcntl(cout_pipe[0], F_SETFL, flags|O_NONBLOCK);
// read from pipe and send it up through a callback method
int stat;
size_t size = 0;
char buffer [ 1000 ];
do
{
while((size = fread(buffer, sizeof(char), sizeof(char)*1000, cout_f))!=0)
{
call_back_function(buffer, size);
}
}while(waitpid(child_pid, &stat, WNOHANG) != -1)
//Do 1 extra read
while((size = fread(buffer, sizeof(char), sizeof(char)*1000, cout_f))!=0)
{
call_back_function(buffer, size);
}
我面临的问题发生在子进程打印到标准输出并在刷新之前(通常)退出时。我想念管道中发送的内容。
这是我的问题:
- 上面的代码安全/正确还是可以改进?
- 有没有办法在子进程死亡的最后一刻读取整个管道,即使它没有刷新其标准输出?
【问题讨论】:
-
只要数据不刷新就不会写入,所以没办法!
-
同意!但是一旦python子进程死亡,管道不应该自动刷新吗?
-
我看不出将管道设置为非阻塞模式的意义。您没有阅读错误流。您在直播结束之前不会阅读。
-
您无需等待。只需在阅读时发送所有内容。这就是您的代码已经完成的工作。摆脱非阻塞模式;摆脱 while(wait(...)) 条件;摆脱最后的阅读;并且只执行第一个读取循环直到流结束。然后调用wait()获取退出码。
-
可能是这样,但如果该进程也在 stderr 上产生,则需要在另一个线程中读取,否则当 stderr 缓冲区填满时,它将阻塞。