【发布时间】:2019-04-10 10:03:08
【问题描述】:
为了了解 Pipe IPC 机制的工作原理,我编写了一个简单的程序,该程序创建了两个使用管道共享数据的子进程。第一个子进程必须从文件中读取数据并将其传递给管道。
之后,第二个子进程必须读取它,将其转换为大写并将其写入另一个文件。从管道读取时,第二个子进程中的 read 系统调用返回 -1。此外,当我执行程序时,在某些情况下,第一个孩子的 printf 不会打印任何内容,而在其他情况下,第二个孩子的 printf 也不会打印。您能否指出导致问题的程序中的错误?
int main(int args[], char * argv[]) {
int fd[2];
long length;
char buff1[250];
char buff2[250];
FILE * fptr1;
FILE * fptr2;
pid_t A, B;
pipe(fd);
A = fork();
if (A == -1) {
printf("error in fork of A\n");
exit(1);
}
if (A == 0) {
fptr1 = fopen(argv[1], "r"); // program receives file names as argument
if (fptr1 == NULL) {
printf("Erro in file open1\n");
exit(1);
}
fseek(fptr1, 0 L, SEEK_END);
length = ftell(fptr1);
fseek(fptr1, 0 L, SEEK_SET);
close(fd[0]);
fread(buff1, length, 1, fptr1);
buff1[length] = '\0';
printf("buff1 = %s", buff1);
write(fd[1], buff1, length);
fclose(fptr1);
exit(0);
} else {
B = fork();
if (B == -1) {
printf("Error in forking child B");
exit(1);
}
if (B == 0) {
fptr2 = fopen(argv[2], "w");
if (fptr2 == NULL) {
printf("Error in file open2\n");
exit(1);
}
close(fd[1]);
int n = read(fd[0], buff2, length);
printf("n = %d\n", n);
upper_string(buff2); // converts characters to uppecase
fwrite(buff2, 1, length, fptr2);
fclose(fptr2);
}
}
return 0;
}
【问题讨论】:
-
看来
length在第二个孩子中是未定义的,因为它没有在任何地方设置。未定义的行为,如果幸运的话可能为零,因此不会从管道中读取任何内容。 -
如果将父代码路径和子代码路径(
fork之后)拆分为不同的函数,则避免此类问题要容易得多。拥有一个在顶部声明局部变量但仅在某些代码路径上初始化的大函数总是很麻烦。 -
哦,如果
read返回-1,你真的应该尝试打印errno。 -
为第二个孩子设置
length解决了未定义的行为。我还在父进程中添加了两个对wait()的调用,这样现在程序就不会挂起。
标签: c