【发布时间】:2021-06-14 01:54:57
【问题描述】:
我需要编写一个程序来请求一个整数,将输入通过管道传递给子进程,在子进程中进行平方,再通过管道返回父进程,然后再请求另一个输入。
我可以在没有循环的情况下执行此操作,但我终其一生都无法弄清楚我需要调用 fork() 和 read() 的顺序。
这是我所拥有的:
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void){
int psocket[2];
int csocket[2];
int csig[2];
int sig = 0;
pid_t child;
if(read(csig[0], &sig, sizeof(int)) == -1)
perror("reading signal");
if(sig){
int square;
if(read(csocket[0], &square, sizeof(int))==-1)
perror("read to child");
square = square * square;
if(write(psocket[1], &square, sizeof(int))==-1)
perror("write to parent");
return 0;
}
while(1){
int value;
sig = 1;
printf(">> ");
scanf("%d", &value);
if(value ==0)
break;
if(write(csocket[1], &value, sizeof(int))==-1)
perror("write to child");
if(write(csig[1], &value, sizeof(int))==-1)
perror("write to signal");
child = fork();
wait(NULL);
if(read(psocket[0], &value, sizeof(int))==-1)
perror("read to parent");
printf("\n>> %d\n", value);
}
return 0;
}
但我在尝试读/写 csig 管道时遇到错误
reading signal: Bad file descriptor
>> 32 //entering a value to test
write to signal: Bad file descriptor
此时我完全迷失了。还有其他方法可以解决这个问题吗?有什么明显的我做错了吗?
编辑:
我意识到我忘了调用 pipe()
我加了
if ((pipe(psocket) < 0) || (pipe(csocket) < 0) || (pipe(csig) < 0)) {
perror("opening stream socket pair");
exit(10);
}
变量初始化后,现在程序挂起。
【问题讨论】:
-
您正在使用未初始化的变量。
-
@shawn 已修复,我认为。
-
您现在(假设我正确解释了您的编辑:如果您实际编辑问题并添加代码会很方便)创建一个管道并立即尝试从中读取。由于没有写入者,读取将永远阻塞。
-
我此时已将其隔离为一个问题,但这让我仍然完全不知道如何解决这个问题。如果我无法调用读取尚未写入的管道,如何让子进程知道它是子进程?如果我在循环之前调用 fork,那么我如何递归调用新进程?
-
孩子会根据
fork()的返回值知道它是一个孩子。您应该每个程序只分叉一次,而不是每个输入一次。