2014-09-03 41 views
0

下面的代码之前,我做:如何从子进程读取标准输出,当后者不刷新其标准输出?

  • 创建1管从分叉处理中读取输出

  • 叉()

  • 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); 
} 

我正面临的问题发生在子进程打印到标准输出并在冲洗前退出(通常)。我想念管道里发出的东西。

这里是我的问题:

  • 是上面的代码安全/正确或能不能改进?
  • 有没有办法在子进程死亡的最后一刻读取整个管道,即使它没有刷新其stdout?
+3

只要数据没有被刷新,就不会写入,因此没办法! – 2014-09-04 00:05:12

+0

同意!但是,一旦蟒蛇子过程死亡,管子是否不应该自动冲洗? – Kam 2014-09-04 00:06:13

+0

@Kam这取决于它是如何死亡。如果它正常退出,所有的'stdio'缓冲区都应该被刷新。如果中止,可能不是。 – EJP 2014-09-04 01:20:20

回答

2

您不必等待。当你阅读它时,只需发送一切。这就是你的代码已经做的。摆脱非阻塞模式;摆脱了(等待(...))条件;摆脱最后的阅读;只需执行第一个读取循环,直到流结束。然后调用wait()来获得退出代码。

如果进程也在stderr上产生,则需要在另一个线程中读取该进程,否则当stderr缓冲区填满时,它将被阻塞。

+0

噢,你是对的,我其实是读了stderr。那么我的问题可以通过上述实施来解决吗? – Kam 2014-09-04 02:16:28

+1

或者,如果您不想要第二个线程,则可以使用select系统调用来等待数据在任一管道上可用。 – wrdieter 2014-09-04 02:23:05

+0

但是我没有得到的是上面代码中的问题。我没有得到什么错误,所以我可以修复它。任何想法? – Kam 2014-09-04 02:25:35

相关问题