C 管道无法进行大量写入

标签 c pipe

写了一个小脚本来处理 php5-cgi使用 fork() , exec()和管道。当输出 php5-cgi 时,下面的脚本运行良好是小。但当它相当大时(在输入文件中使用 <?php phpinfo(); ?> 时),它不会返回任何内容。

#include<netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>

int main(int argc, char const *argv[]) {

  int status;
  int link[2];
  char out[4096];
  char * arg[3]={"php5-cgi","a.php",0};
  if (pipe(link)==-1){
    perror("pipe");
  }
  int pid=fork();
  if (!pid){
    dup2 (link[1], 1);
    close(link[0]);
    execvp("php5-cgi", arg);
  } else {
    waitpid(pid, &status,0);
    close(link[1]); // parent doesn't write
        char reading_buf[1];
        while(read(link[0], reading_buf, 1) > 0){
            write(1, reading_buf, 1);
        }
        close(link[0]);
  }
  printf("%s\n", "end");
  return 0;
}

我认为这是由于管道溢出造成的。我有什么办法可以解决这个问题吗?或者是否有任何替代方法来处理大输出?

最佳答案

管道缓冲区比较小,一般只有几Kbytes。 child 可以写入它直到缓冲区已满;然后进一步的写入将阻塞,直到读取了一些数据。

你的 parent 调用 waitpid在尝试从管道读取之前。所以它正在等待 child 终止。但是如果 child 试图写被阻止,它永远不会终止。所以你永远不会越过 waitpid在这种情况下。

您可能想要做的是移动 waitpidread/write之后环形。然后 child 可以在您阅读时继续写入更多数据。当 read() finally 失败了,很可能是因为 child 已经退出并关闭了它的管道末端。所以你可以做 waitpid在那个时候获取退出状态并收获僵尸。

此外,检查所有系统调用的返回值!并在打开警告的情况下进行编译(这会提醒您您忘记了 #include <sys/wait.h> )。

关于C 管道无法进行大量写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36565255/

相关文章:

c - 这段c代码有什么问题?答案总是零?

r - 在 R : broken pipe error 中传递两个 bash 命令

mysql - 选择一个字段并将其通过管道传递到其他程序

node.js - 如何使用 node.js 从 stdin 逐行流式传输并发送到客户端?

c - mvaddch() 不打印到控制台

python - 在 Python 中查看是否有来自管道的输入?

C:正确释放多维数组的内存

C 从 GitHub 下载 Zip 文件

c - 从键盘输入数据

c - 在 C 中打印字符串数组的元素