gpt4 book ai didi

c - 父进程无法读取子进程在管道中写入的数据

转载 作者:行者123 更新时间:2023-11-30 14:54:57 24 4
gpt4 key购买 nike

这个论坛中有很多与管道读写相关的问题,但我无法解决我的问题。下面的代码片段执行以下操作:

  1. 通过命令行参数filename通过pipe_p传递给子进程
  2. 子进程打开指定的文件,并将其内容写入pipe_c供父进程读取并显示在屏幕上。

一切工作正常,但父进程无法从管道读取数据(因为它没有打印任何内容)。我观察到数据已由子进程成功写入,因为我能够通过子进程 block 中的管道打印内容,但不能在父进程中打印内容。

注意:STEP 4 不起作用

任何人请帮助我。

代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv){

int pipe_p[2], pipe_c[2];
int childpid, c, k = 0;
char buffer[1000] = {0};
FILE *file;

pipe(pipe_p);
pipe(pipe_c);

childpid = fork();

if(childpid){
//parent process block
//STEP 1 -------
close(pipe_p[0]); //closing reading side of pipe
write(pipe_p[1], argv[1], strlen(argv[1]));
close(pipe_p[1]);
//--------------
wait(NULL);
//--------------
//printf("%s\n", "Its working");
//STEP 4 -------
close(pipe_c[1]);
read(pipe_c[0], buffer, sizeof(buffer));
close(pipe_c[0]);
printf("%s\n", buffer);
//--------------
}
else{
//child process block
//sleep(1);
//STEP 2 -------
close(pipe_p[1]);
read(pipe_p[0], buffer, sizeof(buffer));
close(pipe_p[0]);
//printf("%s\n", buffer);
//--------------

//STEP 3 -------
file = fopen(buffer, "r");
while((c = getc(file)) != EOF){
buffer[k++] = c;
}
buffer[k] = 0;
//printf("%s", buffer);
close(pipe_c[0]);
write(pipe_c[1], buffer, strlen(buffer));
close(pipe_c[1]);
//--------------
}

return 0;
}

最佳答案

我在这段代码中发现了五个错误。我将从最不重要到最重要的顺序列出它们。我还没有尝试修复任何错误,因此这些错误背后可能隐藏着更多错误。

  • 您忘记包含 sys/wait.h。编译器应该提示 wait 的隐式声明。 (如果您的编译器没有提出任何投诉,请打开所有警告。)

  • 您没有检查任何系统调用是否失败。 每个系统调用后都应该检查是否失败。当失败时,向 stderr 打印失败的完整描述,包括失败的系统调用的名称、涉及的所有文件的名称(如果有)以及 strerror(errno ),然后使用非零(不成功)退出代码退出程序。如果您这样做了,您会自己发现,事实上,某些事情没有“正常工作”。

  • 相应地,您不会检查子进程是否退出失败。父进程应该执行 waitpid(childpid, &status, 0),而不是 wait(NULL),然后解码退出状态并将消息打印到 stderrWIFEXITED(status) && WEXITSTATUS(status) == 0 之外的任何内容,然后自行退出失败。

  • 在父级中,您在错误的位置调用了 wait。在读取并处理来自 pipe_c 的所有数据后,您需要调用 wait。否则,如果子进程完全填满管道缓冲区,程序就会死锁。 (此外,您需要从管道读取所有数据,而不仅仅是其中的前 1000 个字节。)

  • 在子进程中,缓冲区溢出。您正在从文件中将无限量的数据读取到缓冲区中,但缓冲区具有固定大小。您应该根据需要使用 malloc 和 realloc 来放大它,或者以不大于缓冲区大小的 block 从文件复制到管道>.

我通过在 strace 实用程序下以 -f 模式(因此它跟踪 fork 的两侧)运行程序发现了所有这些问题,输入来自一个大文件。这是一种很有值(value)的调试技术,您应该亲自尝试一下。

关于c - 父进程无法读取子进程在管道中写入的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46393423/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com