我正在尝试正确提示用户输入UNIX管道。我必须使用单个管道创建3个子进程。每个子进程都要求用户输入一个整数并将其写入管道。父进程显示所有三个整数以及将每个整数写入管道的进程的processid。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char argv[]) {
int input = 0;
int pd[2];
int i =0;
int buffer[100];
int output = 0;
if (pipe(pd) == - 1) {
fprintf(stderr, "Pipe Failed");
}
for (i=0; i<3; i++) {
if (fork() == 0) { // child process
printf("\nMy process id is: %d", getpid());
printf("\nEnter an integer: ");
scanf("%d", &input);
if (write(pd[1], &input, sizeof(int)) == -1) {
fprintf(stderr, "Write Failed");
}
return (0); // Return to parent. I am not really sure where this should go
} // end if statement
} // I am not quite sure where the for loop ends
// Parent process
close(pd[1]); // closing the write end
for (i = 0; i < 3; i++) {
if (read(pd[0], &output, sizeof(int) )== -1) {
fprintf(stderr, "Read failed");
}
else {
buffer[i] = output;
printf("Process ID is: %d\n", pid);
}
}
printf("The numbers are %d, %d, %d", buffer[0], buffer[1], buffer[2]);
return(0);
}
编辑后,我现在得到输出:
My process id is: 2897
Enter an integer: My process id is: 2896
Enter an integer:
My process id is: 2898
Enter an integer: 4
Process ID is: 2898
78
Process ID is: 2898
65
Process ID is: 2898
The numbers are 4, 78, 65
这是更接近但我还不确定如何让父母等待子进程。当尝试打印每个数字及其进程ID时,只会打印最新的进程ID。
所有printf语句都在scanf语句之前执行,所以在提示3次之前我不能输入任何内容。
答案 0 :(得分:0)
在任何给定时间,只有一个进程可以与用户通话。您需要安排,以便孩子2在孩子1完成之前不做任何事情,依此类推。最简单的方法是在分离下一个孩子之前连续为每个孩子设置父wait()
。 编辑:这看起来像这样:
for (i = 0; i < 3; i++) {
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
} else if (pid == 0) {
// your existing child code goes here
} else {
// parent:
int status;
if (waitpid(pid, &status, 0) != pid) {
perror("wait");
return 1;
} else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
fprintf(stderr, "child %d unexpected exit %d\n", i, status);
return 1;
}
}
}
由于写入管道的数据量非常短(总共少于PIPE_BUF
个字节; PIPE_BUF
保证至少为512),您可以安全地延迟从管道读取,直到毕竟孩子都退出了。如果孩子们发回更长的信息,就不会出现这种情况。
main
返回一个整数。第一个循环中的return;
语句应为return 0;
,最后需要另一个return 0;
(最后printf
之后)。
您的第一个for
循环在它应该结束的位置结束,即在嵌套的if
语句之后。你可以在它周围放置另一组花括号 - 在for (...)
之后打开大括号,在你有// I am not quite sure
注释的右大括号 - 很多人会考虑到更好的风格,但你不必。
答案 1 :(得分:0)
if (read(pd[0]), &output, sizeof(int) )== -1)
^ // this is wrong
你的括号不正确,但我认为这是一个错字。
只有在读取失败时才更新缓冲区......应该是:
if (read(pd[0], &output, sizeof(int) )== -1) {
fprintf(stderr, "Read failed");
}
else {
buffer[i] = output;
}
虽然可以通过很多方式改进此代码。查看其他答案,并在(-Wall with gcc)
上编辑警告程序