[英]How to make a UNIX pipe prompt for user input correctly?
I am trying to have UNIX pipes correctly prompt for user input. 我试图让UNIX管道正确提示用户输入。 I have to create 3 child processes using a single pipe.
我必须使用单个管道创建3个子进程。 Each child process asks the user to enter an integer and writes it to the pipe.
每个子进程都要求用户输入一个整数并将其写入管道。 The parent process displays all three integers as well as the processid's of the process that wrote each to the pipe.
父进程显示所有三个整数以及将每个整数写入管道的进程的进程ID。
#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);
}
After editing, I now get as output: 编辑后,我现在得到输出:
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
which is a lot closer but I am not yet sure how to make the parent wait for the child processes. 这离我们很近,但我还不确定如何让父级等待子级进程。 When trying to print each number along with it's process id, only the most recent process id is getting printed.
当尝试打印每个数字及其进程ID时,只会打印最新的进程ID。
All of the printf statements execute before the scanf statements so I can't type anything until it prompts 3 times. 所有printf语句在scanf语句之前执行,因此我无法键入任何内容,直到提示3次为止。
Only one process can be talking to the user at any given time. 在任何给定时间,只有一个进程可以与用户对话。 You need to arrange so that child 2 doesn't do anything until child 1 is done, and so on.
您需要进行安排,以使子级2在子级1完成之前不会执行任何操作,依此类推。 The simplest way to do this is to have the parent
wait()
for each child in succession, before forking off the next one. 最简单的方法是在派生下一个孩子之前,先让每个孩子都拥有父
wait()
。 EDIT: That would look something like this: 编辑:看起来像这样:
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;
}
}
}
Since the amount of data written to the pipe is very short (less than PIPE_BUF
bytes in total; PIPE_BUF
is guaranteed to be at least 512), you can safely delay reading from the pipe until after all children have exited. 由于写入管道的数据量非常短(总共少于
PIPE_BUF
字节;保证PIPE_BUF
至少为512),因此可以放心地从管道中读取数据,直到所有子项都退出为止。 This would not be the case if the children were sending back longer messages. 如果孩子们发回更长的消息,情况就不会如此。
main
returns an integer. main
返回一个整数。 Your return;
您的
return;
statement inside the first loop should be return 0;
第一个循环中的语句应
return 0;
and there needs to be another return 0;
并且需要另一个
return 0;
at the very end (after the final printf
). 在最后(最后一次
printf
)。
Your first for
loop ends right where it ought to end, ie after the nested if
statement. 您的第一个
for
循环在应该结束的地方结束,即在嵌套的if
语句之后。 You can put another set of curly braces around it - open brace right after the for (...)
, close brace right where you have the // I am not quite sure
comment - and lots of people would consider that better style, but you don't have to. 您可以在其周围放置另一组花括号-在
for (...)
之后打开花括号,在您拥有// I am not quite sure
地方关闭花括号, // I am not quite sure
发表的评论-很多人会认为这种样式更好,但是您不必。
if (read(pd[0]), &output, sizeof(int) )== -1)
^ // this is wrong
your parenthesis are incorrect but I assume that's a typo. 您的括号不正确,但我认为这是一个错字。
You also update buffer only if read fails... It should be: 您还只有在读取失败的情况下才更新缓冲区...应该是:
if (read(pd[0], &output, sizeof(int) )== -1) {
fprintf(stderr, "Read failed");
}
else {
buffer[i] = output;
}
There are many ways this code could be improved though. 但是,有许多方法可以改进此代码。 Look at other answers and compile your programs with warnings on (-Wall with gcc)
查看其他答案,并在警告下编译您的程序(-gcc带有Wall)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.