在这个论坛中有很多与管道读写有关的问题,但我无法解决我的问题。 下面的代码片段包含以下内容:
一切正常,但父进程无法从管道中读取数据(因为它没有打印任何内容)。 我观察到数据是由子进程成功编写的,因为我能够通过子进程块中的管道打印内容,但不能在父进程中打印。
注意: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;
}
答案 0 :(得分:1)
我在这段代码中看到了五个错误。我将从最不重要到最重要的列出它们。我没有尝试修复任何错误,因此可能有更多隐藏在这些错误背后。
您忘记加入sys/wait.h
。编译器应该抱怨wait
的隐式声明。 (如果您的编译器没有提出任何投诉,请打开所有警告。)
您没有检查是否有任何系统调用失败。 每次系统调用之后都应检查失败。当一个失败时,打印到stderr
失败的完整描述,包括失败的系统调用的名称,涉及的所有文件的名称(如果有的话)和strerror(errno)
然后退出具有非零(不成功)退出代码的程序。如果你这样做了,你就会发现,事实上,某些事情 “工作正常”。
相关地,您没有检查孩子是否退出失败。父级应该执行wait(NULL)
而不是waitpid(childpid, &status, 0)
,然后解码退出状态并向stderr
打印除WIFEXITED(status) && WEXITSTATUS(status) == 0
以外的任何内容的消息,然后自己退出失败。< / p>
在父级中,您在错误的位置呼叫wait
。您需要在阅读并处理wait
的所有数据后致电pipe_c
。否则,如果子进程完全填满管道缓冲区,程序将死锁。 (另外,您需要从管道中读取所有数据,而不仅仅是它的前1000个字节。)
在孩子中,你有一个缓冲区溢出。您正在从文件中将无限量的数据读入buffer
,但buffer
具有固定的大小。您应该根据需要使用malloc
和realloc
进行放大,或者将文件从文件复制到不超过buffer
大小的数据包。
我通过strace
实用程序在-f
模式下运行程序(因此它跟踪fork的两侧),并使用大文件的输入来发现所有这些问题。这是一种有价值的调试技术,您应该亲自尝试。