con*_*st6 7 c fork stdout pipe nonblocking
这似乎是一件相当普遍的事情,而且我已经设法自学了我需要的一切,除了我现在有一个问题,这是我的故障排除.
int nonBlockingPOpen(char *const argv[]){
int inpipe;
pid_t pid;
/* open both ends of pipe nonblockingly */
pid = fork();
switch(pid){
case 0: /*child*/
sleep(1); /*child should open after parent has open for reading*/
/*redirect stdout to opened pipe*/
int outpipe = open("./fifo", O_WRONLY);
/*SHOULD BLOCK UNTIL MAIN PROCESS OPENS FOR WRITING*/
dup2(outpipe, 1);
fcntl(1, F_SETFL, fcntl(1, F_GETFL) | O_NONBLOCK);
printf("HELLO WORLD I AM A CHILD PROCESS\n");
/*This seems to be written to the pipe immediately, blocking or not.*/
execvp(*argv, argv);
/*All output from this program, which outputs "one" sleeps for 1 second
*outputs "two" sleeps for a second, etc, is captured only after the
*exec'd program exits!
*/
break;
default: /*parent*/
inpipe = open("./fifo", O_RDONLY | O_NONBLOCK);
sleep(2);
/*no need to do anything special here*/
break;
}
return inpipe;
}
Run Code Online (Sandbox Code Playgroud)
为什么子进程每次生成一行时都不会将其stdout写入管道?在execvp或dup2的工作方式中是否有一些我缺少的东西?我知道我对这一切的处理方式有点奇怪,但我找不到另一种以编程方式捕获闭源二进制文件输出的方法.
我猜你只能在退出后获得 exec'd 程序的输出,因为它不会在每条消息后刷新。如果是这样,您从外部无能为力。
我不太确定这与您问题中阻塞和非阻塞 I/O 之间的选择有何关系。非阻塞写入可能完全或部分失败:调用不会阻塞程序直到管道中有可用空间,而是立即返回并表示它无法写入应有的所有内容。非阻塞 I/O 既不会使缓冲区变大,也不会强制刷新输出,并且某些程序可能对其支持不佳。
您不能强制刷新正在执行的纯二进制程序。如果您认为非阻塞 I/O 是该问题的解决方案,那么抱歉,但恐怕它是相当正交的。
编辑:好吧,如果 exec'd 程序仅使用 libc 提供的缓冲(不实现自己的)并且是动态链接的,则可以通过将其链接到刷新每次写入的修改后的 libc 来强制它刷新。这将是一个孤注一掷的措施。仅当其他一切都失败时才尝试。