我正在尝试让父进程接受4个整数变量(a,b,c和x)的用户输入,并将它们传递给子进程。子进程计算ax ^ 2 + bx + c并将结果r传递给父进程,后者显示它。
使用我现在的代码,任何输入都会得到1的结果。打印语句的行为让我觉得只有x被读取,但即使我尝试将x * x转换为r,我也不会得到正确的解决方案。我能做错什么?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#define PIPE_INPUT 0
#define PIPE_OUTPUT 1
#define INDENT 20
void testError(int err, const char * str){
if ( err < 0 ){
perror(str);
exit( EXIT_FAILURE );
}
}
int main(){
int fd_toChild[2];
int fd_toParent[2];
int buff[20];
pid_t pid;
testError( pipe(fd_toChild), "pipe" );
testError( pipe(fd_toParent), "pipe" );
testError( pid = fork(), "fork" );
int a;
int b;
int c;
int x;
int r;
if (pid > 0){
// this is the parent
int status;
while(1){
close( fd_toChild[PIPE_INPUT] );
close( fd_toParent[PIPE_OUTPUT] );
printf("This program will evaluate a polynomial a(x^2) + bx + c. \n");
printf("Please input an integer value for a: ");
scanf("%d", &a);
write(fd_toChild[PIPE_OUTPUT], &a, sizeof(a));
printf("Parent writes value %d to a \n", a);
printf("Please input an integer value for b: ");
scanf("%d", &b);
write(fd_toChild[PIPE_OUTPUT], &b, sizeof(b));
printf("Parent writes value %d to b \n", b);
printf("Please input an integer value for c: ");
scanf("%d", &c);
write(fd_toChild[PIPE_OUTPUT], &c, sizeof(c));
printf("Parent writes value %d to c \n", c);
printf("Please input an integer value for x: ");
scanf("%d", &x);
write(fd_toChild[PIPE_OUTPUT], &x, sizeof(x));
printf("Parent writes value %d to x \n", x);
close( fd_toChild[PIPE_OUTPUT] );
close( fd_toParent[PIPE_INPUT] );
read(fd_toParent[PIPE_INPUT], buff, sizeof(r));
pid = wait(&status);
fprintf(stdout, "Parent received back the result %d.\n", r);
printf("The polynomial evaluates to %d \n", r);
close( fd_toParent[PIPE_OUTPUT] );
break;
}
}
else{
// this is child
close( fd_toChild[PIPE_OUTPUT] );
close( fd_toParent[PIPE_INPUT] );
while(1){
close( fd_toChild[PIPE_OUTPUT] );
close( fd_toParent[PIPE_INPUT] );
read(fd_toChild[PIPE_INPUT], buff, sizeof(a));
printf("Child reads value %d from a \n", a);
read(fd_toChild[PIPE_INPUT], buff, sizeof(b));
printf("Child reads value %d from b \n", b);
read(fd_toChild[PIPE_INPUT], buff, sizeof(c));
printf("Child reads value %d from c \n", c);
read(fd_toChild[PIPE_INPUT], buff, sizeof(x));
printf("Child reads value %d from x \n", x); r = a * x * x + b * x + c;
printf("x is %d", x); printf("r is %d", r);
write(fd_toParent[PIPE_OUTPUT], buff, sizeof(r));
fprintf(stdout, "%*sChild is all done\n", INDENT, "");
close( fd_toChild[PIPE_INPUT] );
}
}
return EXIT_SUCCESS;
}
答案 0 :(得分:0)
你有一些东西在这里抛弃了你的程序。 @gudok已经指出了一个问题,你关闭了fd_toParent[PIPE_INPUT]
,然后在以下情况后立即尝试读取它:
close( fd_toChild[PIPE_OUTPUT] );
close( fd_toParent[PIPE_INPUT] );
// just closed on the preceding line
read(fd_toParent[PIPE_INPUT], buff, sizeof(r));
另一个问题是在子进程中,您在计算值中要尝试read
:
read(fd_toChild[PIPE_INPUT], buff, sizeof(a));
printf("Child reads value %d from a \n", a);
在此,您将buff
作为read
缓冲区传递,然后尝试从a
进行操作/打印。这使得a
未初始化,这可以解释为什么在打印时你只是零回零。相反,您可以使用系数变量的地址运算符&
:
read(fd_toParent[PIPE_INPUT], &a, sizeof(a));
这适用于b
,c
和x
。
当尝试在父母中打印出结果时:
read(fd_toParent[PIPE_INPUT], buff, sizeof(r));
pid = wait(&status);
fprintf(stdout, "Parent received back the result %d.\n", r);
printf("The polynomial evaluates to %d \n", r);
close( fd_toParent[PIPE_OUTPUT] );
您在read(fd_toParent[PIPE_INPUT], buff, sizeof(r));
中传递的buff
行,但打印出printf(The polynomial evaluates to %d \n", r)
您打印的r
在父进程内未初始化。
您还将大部分逻辑封闭在while(1)
循环中。由于父进程中的break
,这不会影响程序的最终结果,但是如果改变父进程循环,重复调用close
将关闭所有结束管道
while(1){
....
close( fd_toChild[PIPE_OUTPUT] );
close( fd_toParent[PIPE_INPUT] );
}
如果没有break
你的管道没有任何用处。
我进行了多次编辑以显示代码的工作版本:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#define PIPE_INPUT 0
#define PIPE_OUTPUT 1
#define INDENT 20
void testError(int err, const char * str)
{
if (err < 0) {
perror(str);
exit( EXIT_FAILURE );
}
}
int main(int argc, char *argv[])
{
int fd_toChild[2], fd_toParent[2], buff;
pid_t pid;
testError( pipe(fd_toChild), "pipe" );
testError( pipe(fd_toParent), "pipe" );
testError( pid = fork(), "fork" );
int a, b, c, x, r;
if (pid > 0){
// this is the parent
int status;
close( fd_toChild[PIPE_INPUT] );
close( fd_toParent[PIPE_OUTPUT] );
printf("This program will evaluate a polynomial a(x^2) + bx + c. \n");
printf("Please input an integer value for a: ");
scanf("%d", &a);
write(fd_toChild[PIPE_OUTPUT], &a, sizeof(a));
printf("Parent writes value %d to a \n", a);
sleep(1);
printf("Please input an integer value for b: ");
scanf("%d", &b);
write(fd_toChild[PIPE_OUTPUT], &b, sizeof(b));
printf("Parent writes value %d to b \n", b);
sleep(1);
printf("Please input an integer value for c: ");
scanf("%d", &c);
write(fd_toChild[PIPE_OUTPUT], &c, sizeof(c));
printf("Parent writes value %d to c \n", c);
sleep(1);
printf("Please input an integer value for x: ");
scanf("%d", &x);
write(fd_toChild[PIPE_OUTPUT], &x, sizeof(x));
printf("Parent writes value %d to x \n", x);
sleep(1);
// XXX you close then attempt to read from it
//close( fd_toParent[PIPE_INPUT] );
read(fd_toParent[PIPE_INPUT], &buff, sizeof(buff));
pid = wait(&status);
// XXX Here you are showing the results as your uninitialized variable "r"
fprintf(stdout, "Parent received back the result %d.\n", buff);
printf("The polynomial evaluates to %d \n", buff);
close( fd_toChild[PIPE_OUTPUT] );
close( fd_toParent[PIPE_OUTPUT] );
} else {
// this is child
close( fd_toChild[PIPE_OUTPUT] );
close( fd_toParent[PIPE_INPUT] );
read(fd_toChild[PIPE_INPUT], &a, sizeof(a));
printf("Child reads value %d from a \n", a);
read(fd_toChild[PIPE_INPUT], &b, sizeof(b));
printf("Child reads value %d from b \n", b);
read(fd_toChild[PIPE_INPUT], &c, sizeof(c));
printf("Child reads value %d from c \n", c);
read(fd_toChild[PIPE_INPUT], &x, sizeof(x));
printf("Child reads value %d from x \n", x);
r = a * x * x + b * x + c;
printf("x is %d\n", x);
printf("r is %d\n", r);
write(fd_toParent[PIPE_OUTPUT], &r, sizeof(r));
fprintf(stdout, "%*sChild is all done\n", 0, "");
close( fd_toChild[PIPE_INPUT] );
close( fd_toParent[PIPE_OUTPUT] );
}
return EXIT_SUCCESS;
}